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