Oh, no. I've accidentally done the *fix*, even though that is contrary to my own claim.
I don't like the cross-talk of compile-time and run-time variables. An related issue is bug 3449, but it has been opposed by Walter. http://d.puremagic.com/issues/show_bug.cgi?id=3449 A small example of bug 3449: ---- void main() { struct Foo1 { const int bar; } pragma(msg, Foo1.sizeof); // Prints "4" Foo1 foo1; auto p1 = &foo1.bar; // Succeeds to compile, as excepced. struct Foo2 { const int bar = 123; } pragma(msg, Foo2.sizeof); // Prints "1", not "4" Foo2 foo2; auto p2 = &foo2.bar; // Error: constant 123 is not an lvalue } Why cannot get address of foo2.bar? The answer is: compiler makes Foo2.bar a manifest constant, because its type is not mutable and has an initializer. --- With current dmd, *all* of variable declarations, that has non mutable type and initializer, are _speculatively_ interpreted in compile time (== CTFE-ed). If it is succeeds, the declaration will be treated as same as manifest constant. That is the reason of you explained *bug* and bug 3449. I think the *implicit interpretation* is inherited from D1, and if go back further, will reach to C++ constant variable. BUT, in D2, we have the 'enum' declaration, which express the declaration is really manifest constant. So, the muddy interpretation just confuses many D user's, and less benefit. I think we should separate run-time variable declarations and compile time ones, to moderate the leaning curve. Regards. Kenji Hara 2012/7/23 bearophile <bearophileh...@lycos.com>: > After a discussion in D.learn started by someone else, after a suggestion of > mine Timon Gehr has added a bug report: > > http://d.puremagic.com/issues/show_bug.cgi?id=8400 > > But the bug was fixed in the opposite way of what I was thinking. > > The problem was that the length of global immutable arrays arrays is seen as > a compile-time constant. > Instead of fixing that, Issue 8400 has done the opposite, now even the > lenght of local immutable arrays is seen sometimes as a compile-time > constant, and example: > > > int[] foo(in int n) pure nothrow { > int[] a; > foreach (i; 0 .. n) > a ~= i * 10; > return a; > } > void main() { > import core.stdc.stdio: printf; > immutable int[] A = foo(5); > int[A.length] B; > printf("%zd\n", B.length); > } > > > > The asm, compiled with -release: > > _D4temp3fooFNaNbxiZAi comdat > L0: enter 018h,0 > push EBX > push ESI > mov dword ptr -018h[EBP],0 > mov dword ptr -014h[EBP],0 > mov dword ptr -010h[EBP],0 > mov -0Ch[EBP],EAX > L1E: mov EAX,-010h[EBP] > cmp EAX,-0Ch[EBP] > jge L48 > lea ECX,-010h[EBP] > mov EDX,[ECX] > lea EBX,[EDX*4][EDX] > add EBX,EBX > push EBX > lea ESI,-018h[EBP] > push ESI > mov EAX,offset FLAT:_D11TypeInfo_Ai6__initZ > push EAX > call near ptr __d_arrayappendcT > add ESP,0Ch > inc dword ptr -010h[EBP] > jmp short L1E > L48: mov EDX,-014h[EBP] > mov EAX,-018h[EBP] > pop ESI > pop EBX > leave > ret > > __Dmain comdat > L0: enter 018h,0 > push EBX > push ESI > push 5 > mov EAX,offset FLAT:_D11TypeInfo_Ai6__initZ > push EAX > call near ptr __d_arrayliteralTX > mov dword ptr [EAX],0 > mov dword ptr 4[EAX],0Ah > mov dword ptr 8[EAX],014h > mov dword ptr 0Ch[EAX],01Eh > mov dword ptr 010h[EAX],028h > mov ECX,EAX > mov EBX,5 > lea EDX,-018h[EBP] > xor EAX,EAX > mov [EDX],EAX > mov 4[EDX],EAX > mov 8[EDX],EAX > mov 0Ch[EDX],EAX > mov 010h[EDX],EAX > push 5 > mov ESI,offset FLAT:_DATA > push ESI > call near ptr _printf > xor EAX,EAX > add ESP,010h > pop ESI > pop EBX > leave > ret > > > > This code too compiles, so A is sometimes computed at run-time and sometimes > at compile-time: > > int[] foo(in int n) pure nothrow { > int[] a; > foreach (i; 0 .. n) > a ~= i * 10; > return a; > } > void main() { > import core.stdc.stdio: printf; > int n = 5; > immutable int[] A = foo(n); > } > > > > Now immutable arrays are sometimes seen as enums. I think this is a problem. > I think in D compile-time is run only if it's evaluated in a context where > compile-time values are required. But now the situation is more muddy, > because knowing n at compile-time is not a way to ask A to be computed at > compile-time. > > Another problem is that compile-time arrays in many situations are not > efficient, they gets copied every time you use them, and I think that > __d_arrayliteralTX performs a heap allocation. So now both enum and > immutable arrays perform heap allocations every time you use them, but only > in some situations. > > I think this is a messy situation, I think the fix for bug 8400 should be > undone, and I think Issue 8400 should be fixed the other way, turning global > immutable arrays too into run-time entities. > > The bug was fixed by Hara and accepted by Walter, both of them are very > intelligent, so maybe I am just very wrong :-) > > Bye, > bearophile