digitalmars.D.learn - What does this compile-time error mean?
- Alexandr Druzhinin (22/22) Feb 24 2013 This code:
- Jonathan M Davis (21/50) Feb 24 2013 Because main_cont is module-level variable, it must be initialized with ...
- Alexandr Druzhinin (2/22) Feb 24 2013 I see. Thank you!
- Maxim Fomin (47/61) Feb 24 2013 I would say that it is arbitrary restriction
- Timon Gehr (2/18) Feb 24 2013 Yes, IIRC Don once stated that it is a problem with DMD's architecture.
- Jonathan M Davis (8/29) Feb 24 2013 Most restrictions in CTFE are a limitation of the current implementation...
- Don (4/47) Feb 25 2013 Yeah, this one is a limitation of the runtime, not of CTFE. CTFE
This code: import std.stdio; import std.container; import std.range; auto main_cont = redBlackTree(iota(0, 100, 10).array); void main() { writeln(main_cont.array); } at compilation with dmd 2.062 generates: D:\applications\D\dmd2\windows\bin\..\..\src\druntime\import core\memory.d(316): Error: gc_malloc cannot be interpreted at compile time, because it has no available source code D:\applications\D\dmd2\windows\bin\..\..\src\phobos\std\array.d(321): called from here: malloc(_param_0 * 4u, 2u) D:\applications\D\dmd2\windows\bin\..\..\src\phobos\std\array.d(272): called from here: arrayAllocImpl(_param_0) D:\applications\D\dmd2\windows\bin\..\..\src\phobos\std\array.d(45): called from here: uninitializedArray(r.length()) src\main.d(5): called from here: array(iota(0, 100, 10)) src\main.d(5): called from here: redBlackTree(array(iota(0, 100, 10))) Is it my error?
Feb 24 2013
On Sunday, February 24, 2013 15:42:33 Alexandr Druzhinin wrote:This code: import std.stdio; import std.container; import std.range; auto main_cont = redBlackTree(iota(0, 100, 10).array); void main() { writeln(main_cont.array); } at compilation with dmd 2.062 generates: D:\applications\D\dmd2\windows\bin\..\..\src\druntime\import\core\memory.d(3 16): Error: gc_malloc cannot be interpreted at compile time, because it has no available source code D:\applications\D\dmd2\windows\bin\..\..\src\phobos\std\array.d(321): called from here: malloc(_param_0 * 4u, 2u) D:\applications\D\dmd2\windows\bin\..\..\src\phobos\std\array.d(272): called from here: arrayAllocImpl(_param_0) D:\applications\D\dmd2\windows\bin\..\..\src\phobos\std\array.d(45): called from here: uninitializedArray(r.length()) src\main.d(5): called from here: array(iota(0, 100, 10)) src\main.d(5): called from here: redBlackTree(array(iota(0, 100, 10))) Is it my error?Because main_cont is module-level variable, it must be initialized with a value at compile time. Classes can be used at compile time (at least some of the time), but they cannot stick around between compile time and runtime, meaning that you could potentially use them in a CTFE function, but you can't initialize a module-level or static variable (or enum) with them, and you're attempting to initialize maint_cont with a RedBlackTree, which is a class. It won't work. Now, on top of that, given those particular errors, it looks like there may be other issues beyond that which prevent RedBlackTree and/or std.array.array from being used at compile time at all, but even if it were perfectly useable at compile time, it still couldn't persist after the code is compiled and therefore could not be assigned to maint_cont. If you want to have main_cont be a RedBlackTree, you need to iniatialize it at runtime. To do that, you could do that something like RedBlackTree!int main_cont; static this() { main_cont = redBlackTree(iota(0, 100, 10).array()); } - Jonathan M Davis
Feb 24 2013
24.02.2013 15:59, Jonathan M Davis пишет:Because main_cont is module-level variable, it must be initialized with a value at compile time. Classes can be used at compile time (at least some of the time), but they cannot stick around between compile time and runtime, meaning that you could potentially use them in a CTFE function, but you can't initialize a module-level or static variable (or enum) with them, and you're attempting to initialize maint_cont with a RedBlackTree, which is a class. It won't work. Now, on top of that, given those particular errors, it looks like there may be other issues beyond that which prevent RedBlackTree and/or std.array.array from being used at compile time at all, but even if it were perfectly useable at compile time, it still couldn't persist after the code is compiled and therefore could not be assigned to maint_cont. If you want to have main_cont be a RedBlackTree, you need to iniatialize it at runtime. To do that, you could do that something like RedBlackTree!int main_cont; static this() { main_cont = redBlackTree(iota(0, 100, 10).array()); } - Jonathan M DavisI see. Thank you!
Feb 24 2013
On Sunday, 24 February 2013 at 09:00:17 UTC, Jonathan M Davis wrote:Because main_cont is module-level variable, it must be initialized with a value at compile time. Classes can be used at compile time (at least some of the time), but they cannot stick around between compile time and runtime, meaning that you could potentially use them in a CTFE function, but you can't initialize a module-level or static variable (or enum) with them, and you're attempting to initialize maint_cont with a RedBlackTree, which is a class. It won't work. - Jonathan M DavisI would say that it is arbitrary restriction class C { } struct S { int[] array; this(int val[]) { array = val; } } //can issue call to runtime allocator enum EA : int[] { //does not complain that gc_malloc() is absent A = [1, 6] } //can evaluate dynamically allocated referenced type at CT static assert(EA.init == [1, 6]); // can have module-level object // evaluated to non-trivial CTFE initializer EA ea; enum ES : S { //can issue call to constructor A = S([2, 9]) } // can evaluate this static assert (ES.init.array == [2, 9]); // can have module-level object // evaluated to non-trivial CTFE initializer ES es; //but classes don't work enum EC : C { // B = new C //NG - why not here? // why cannot call ga_malloc here? A = null } void main() { assert(ea == [1, 6]); assert(es.array == [2, 9]); C c; int[] arr; assert (c is null && arr is null); EA e; assert(e !is null && e == [1, 6]); } In short, if interpreter can dynamically allocate reference types like dynamic arrays, store them in TLS storage and interpret trivial CTFE struct constructor, it can handle classes. At least it can work without gc_malloc source.
Feb 24 2013
On 02/24/2013 01:59 PM, Maxim Fomin wrote:On Sunday, 24 February 2013 at 09:00:17 UTC, Jonathan M Davis wrote:Yes, IIRC Don once stated that it is a problem with DMD's architecture.Because main_cont is module-level variable, it must be initialized with a value at compile time. Classes can be used at compile time (at least some of the time), but they cannot stick around between compile time and runtime, meaning that you could potentially use them in a CTFE function, but you can't initialize a module-level or static variable (or enum) with them, and you're attempting to initialize maint_cont with a RedBlackTree, which is a class. It won't work. - Jonathan M DavisI would say that it is arbitrary restriction ...
Feb 24 2013
On Sunday, February 24, 2013 14:05:26 Timon Gehr wrote:On 02/24/2013 01:59 PM, Maxim Fomin wrote:Most restrictions in CTFE are a limitation of the current implementation rather than being something that's literally impossible to do (though some like the lack of source code aren't). In the case of a class, I believe that it would have to basically serialize the class at compile time and then deserialize it at runtime to do it. That's certainly possible to do in theory, but it's well beyond what the current CTFE implementation can do. - Jonathan M DavisOn Sunday, 24 February 2013 at 09:00:17 UTC, Jonathan M Davis wrote:Yes, IIRC Don once stated that it is a problem with DMD's architecture.Because main_cont is module-level variable, it must be initialized with a value at compile time. Classes can be used at compile time (at least some of the time), but they cannot stick around between compile time and runtime, meaning that you could potentially use them in a CTFE function, but you can't initialize a module-level or static variable (or enum) with them, and you're attempting to initialize maint_cont with a RedBlackTree, which is a class. It won't work. - Jonathan M DavisI would say that it is arbitrary restriction ...
Feb 24 2013
On Sunday, 24 February 2013 at 19:13:47 UTC, Jonathan M Davis wrote:On Sunday, February 24, 2013 14:05:26 Timon Gehr wrote:Yeah, this one is a limitation of the runtime, not of CTFE. CTFE has no problem with it.On 02/24/2013 01:59 PM, Maxim Fomin wrote:Most restrictions in CTFE are a limitation of the current implementation rather than being something that's literally impossible to do (though some like the lack of source code aren't). In the case of a class, I believe that it would have to basically serialize the class at compile time and then deserialize it at runtime to do it. That's certainly possible to do in theory, but it's well beyond what the current CTFE implementation can do. - Jonathan M DavisOn Sunday, 24 February 2013 at 09:00:17 UTC, Jonathan M Davis wrote:Yes, IIRC Don once stated that it is a problem with DMD's architecture.Because main_cont is module-level variable, it must be initialized with a value at compile time. Classes can be used at compile time (at least some of the time), but they cannot stick around between compile time and runtime, meaning that you could potentially use them in a CTFE function, but you can't initialize a module-level or static variable (or enum) with them, and you're attempting to initialize maint_cont with a RedBlackTree, which is a class. It won't work. - Jonathan M DavisI would say that it is arbitrary restriction ...
Feb 25 2013