Thread overview | ||||||||
---|---|---|---|---|---|---|---|---|
|
March 19, 2019 Compile-time associative array | ||||
---|---|---|---|---|
| ||||
Hi, I want to use a constant associative array in a ctfe-able function. Example: string ctfeableFunction() { return Foo["foo"]; } Then I force ctfe with: enum res = ctfeableFunction(); When I use an enum like: enum Foo = ["foo" : "bar"]; It works fine. D-Scanner keep saying to me: This enum may lead to unnecessary allocation at run-time. Use 'static immutable [...] instead' But it lead to: Error: static variable Foo cannot be read at compile time. So is the only way to make ctfe-able associative array is to use enum instead of static immutable ? |
March 19, 2019 Re: Compile-time associative array | ||||
---|---|---|---|---|
| ||||
Posted in reply to boolangery | On Tuesday, 19 March 2019 at 08:50:15 UTC, boolangery wrote:
> Hi,
>
> I want to use a constant associative array in a ctfe-able function.
>
> Example:
>
> string ctfeableFunction()
> {
> return Foo["foo"];
> }
>
> Then I force ctfe with:
>
> enum res = ctfeableFunction();
>
> When I use an enum like:
>
> enum Foo = ["foo" : "bar"];
>
> It works fine.
>
> D-Scanner keep saying to me: This enum may lead to unnecessary allocation at run-time. Use 'static immutable [...] instead'
>
> But it lead to: Error: static variable Foo cannot be read at compile time.
>
> So is the only way to make ctfe-able associative array is to use enum instead of static immutable ?
Yes, I think so. If you would use the enum AA multiple times, it would allocate a new AA each time, that is wat D-Scanner warns against. I am not sure how the CTFE interpreter is implemented, it could be that a new AA is allocated each time you call ctfeableFunction, at compile time. But unless you also call it at runtime, there should be no extra run time allocations.
If you need the AA at run time as well, I would create a static immutable version for that, initialised with the enum.
Beware that a CT AA stores its elements in a different order than a RT AA, which you would notice in a foreach, for example.
|
March 19, 2019 Re: Compile-time associative array | ||||
---|---|---|---|---|
| ||||
Posted in reply to Bastiaan Veelo | On 3/19/19 7:22 PM, Bastiaan Veelo wrote:
> Beware that a CT AA stores its elements in a different order than a RT AA, which you would notice in a foreach, for example.
Yes, this is the issue -- the runtime AA depends on druntime, which is not available to the compiler. The compiler has its own AA implementation that it uses for CTFE.
The internals will not be the same, which is why you can't construct one at compile-time and use it at runtime (the enum just recreates it at runtime when used).
-Steve
|
March 20, 2019 Re: Compile-time associative array | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On Tuesday, 19 March 2019 at 23:41:58 UTC, Steven Schveighoffer wrote:
> On 3/19/19 7:22 PM, Bastiaan Veelo wrote:
>
>> Beware that a CT AA stores its elements in a different order than a RT AA, which you would notice in a foreach, for example.
>
> Yes, this is the issue -- the runtime AA depends on druntime, which is not available to the compiler. The compiler has its own AA implementation that it uses for CTFE.
>
> The internals will not be the same, which is why you can't construct one at compile-time and use it at runtime (the enum just recreates it at runtime when used).
>
> -Steve
Got it ! Thank you, so I need to write:
enum string[string] CtfeFoo = ["foo" : "bar"];
static immutable string[string] Foo;
static this()
{
Foo = CtfeFoo;
}
string ctfeableFunction()
{
if (__ctfe)
return CtfeFoo["foo"];
else
return Foo["foo"];
}
void main()
{
enum a = ctfeableFunction();
auto b = ctfeableFunction();
}
|
March 20, 2019 Re: Compile-time associative array | ||||
---|---|---|---|---|
| ||||
Posted in reply to boolangery | On Wednesday, 20 March 2019 at 08:11:27 UTC, boolangery wrote:
> Got it ! Thank you, so I need to write:
>
> enum string[string] CtfeFoo = ["foo" : "bar"];
> static immutable string[string] Foo;
>
> static this()
> {
> Foo = CtfeFoo;
> }
>
> string ctfeableFunction()
> {
> if (__ctfe)
> return CtfeFoo["foo"];
> else
> return Foo["foo"];
> }
>
> void main()
> {
> enum a = ctfeableFunction();
> auto b = ctfeableFunction();
> }
Yes, that looks correct to me.
|
March 20, 2019 Re: Compile-time associative array | ||||
---|---|---|---|---|
| ||||
Posted in reply to boolangery | On 3/20/19 4:11 AM, boolangery wrote:
> On Tuesday, 19 March 2019 at 23:41:58 UTC, Steven Schveighoffer wrote:
>> On 3/19/19 7:22 PM, Bastiaan Veelo wrote:
>>
>>> Beware that a CT AA stores its elements in a different order than a RT AA, which you would notice in a foreach, for example.
>>
>> Yes, this is the issue -- the runtime AA depends on druntime, which is not available to the compiler. The compiler has its own AA implementation that it uses for CTFE.
>>
>> The internals will not be the same, which is why you can't construct one at compile-time and use it at runtime (the enum just recreates it at runtime when used).
>>
>> -Steve
>
> Got it ! Thank you, so I need to write:
>
> enum string[string] CtfeFoo = ["foo" : "bar"];
> static immutable string[string] Foo;
>
> static this()
> {
> Foo = CtfeFoo;
> }
>
> string ctfeableFunction()
> {
> if (__ctfe)
> return CtfeFoo["foo"];
> else
> return Foo["foo"];
> }
Ugh, yes, that's required.
Probably can be abstracted in a template.
-Steve
|
Copyright © 1999-2021 by the D Language Foundation