| Thread overview | |||||||||
|---|---|---|---|---|---|---|---|---|---|
|
February 24, 2013 What does this compile-time error mean? | ||||
|---|---|---|---|---|
| ||||
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?
| ||||
February 24, 2013 Re: What does this compile-time error mean? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Alexandr Druzhinin | 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
| |||
February 24, 2013 Re: What does this compile-time error mean? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | 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 Davis
>
I see. Thank you!
| |||
February 24, 2013 Re: What does this compile-time error mean? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | 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 Davis
I 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.
| |||
February 24, 2013 Re: What does this compile-time error mean? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Maxim Fomin | On 02/24/2013 01:59 PM, Maxim Fomin wrote:
> 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 Davis
>
> I would say that it is arbitrary restriction
>...
Yes, IIRC Don once stated that it is a problem with DMD's architecture.
| |||
February 24, 2013 Re: What does this compile-time error mean? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | On Sunday, February 24, 2013 14:05:26 Timon Gehr wrote:
> On 02/24/2013 01:59 PM, Maxim Fomin wrote:
> > 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 Davis
> >
> > I would say that it is arbitrary restriction
> >
> >...
>
> Yes, IIRC Don once stated that it is a problem with DMD's architecture.
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 Davis
| |||
February 25, 2013 Re: What does this compile-time error mean? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | 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:
>> On 02/24/2013 01:59 PM, Maxim Fomin wrote:
>> > 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 Davis
>> >
>> > I would say that it is arbitrary restriction
>> >
>> >...
>>
>> Yes, IIRC Don once stated that it is a problem with DMD's architecture.
>
> 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 Davis
Yeah, this one is a limitation of the runtime, not of CTFE. CTFE has no problem with it.
| |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply