non-constant error for module AA"s

spir denis.spir at gmail.com
Tue Jan 25 04:40:41 PST 2011


On 01/25/2011 09:13 AM, Lars T. Kyllingstad wrote:
> On Mon, 24 Jan 2011 10:45:03 -0500, Andrej Mitrovic wrote:
>
>> Is this a bug?
>>
>> import std.stdio;
>>
>> string[string] values = ["abc":"abc", "def":"def"];
>>
>> void main()
>> {
>>      string[string] values2 = ["abc":"abc", "def":"def"];
>> }
>>
>>
>> test.d(3): Error: non-constant expression ["abc":"abc","def":"def"]
>>
>> What's non-constant about that expression?
>
>
> My guess would be that using an AA literal is just syntax sugar for
> calling an AA construction function, and that said function isn't
> CTFEable.
>
> When you specify an initial value for a global, that value must be a
> compile-time constant.  If it's not, as in this case, the correct thing
> to do is to use a module constructor:
>
>    string[string] values;
>    static this()
>    {
>        values = [ "abc":"abc", "def":"def" ];
>    }
>
> It is ONLY a good idea to use an enum array if you know you will be doing
> all lookups at compile time.  If the key you're looking for is just known
> at run time, the AA will be constructed anew for each lookup (I think),
> which is hideously expensive.
>
>    enum string[string] values = [ "abc":"def", "ghi":"jkl" ];
>
>    // This is fine, because it is done at compile time.
>    // It's essentially the same as:  auto s = "def";
>    auto s = values["abc"];
>
>    // This is a no-no, because it evaluates to something
>    // like:  auto aa = values; auto s = aa[key];
>    auto key = "abc";
>    auto s = values[key];
>
> Here's an example program that demonstrates the difference.  On my
> machine, the enum AA version takes 22x longer than the "normal" AA
> version.
>
>
> import std.datetime, std.stdio;
>
>
> enum string[string] enumAA = [ "abc" : "abc", "def" : "def" ];
>
> string[string] normalAA;
> static this()
> {
>      normalAA = [ "abc" : "abc", "def" : "def" ];
> }
>
>
> void main()
> {
>      enum max = 10_000_000;
>      StopWatch sw;
>      string lookup1 = "abc";
>      string lookup2 = "def";
>
>      sw.start();
>      foreach (i; 0 .. max)
>      {
>          auto a = enumAA[lookup1];
>          auto b = enumAA[lookup2];
>      }
>      sw.stop();
>      writeln(sw.peek().seconds);
>
>      sw.reset();
>
>      sw.start();
>      foreach (i; 0 .. max)
>      {
>          auto a = normalAA[lookup1];
>          auto b = normalAA[lookup2];
>      }
>      sw.stop();
>      writeln(sw.peek().seconds);
> }

Waow, thank you, Lars, /this/ is an explanation.
Now, why doesn't D make an enum aa a normal variable like your "normal aa" (but 
evaluated at compile-time instead of import time)?

Normal
-- 
_________________
vita es estrany
spir.wikidot.com



More information about the Digitalmars-d-learn mailing list