In what order static if conditions are evaluated?
Timon Gehr
timon.gehr at gmx.ch
Thu Mar 28 11:24:18 PDT 2013
On 03/28/2013 02:34 PM, "Artur Zawłocki" <artur.zawlocki at gmail.com>" wrote:
> On Thursday, 28 March 2013 at 11:52:26 UTC, Don wrote:
>>
>> Yes, it currently evaluates it top to bottom.
>
> As long as all the static if's in question are in a single scope. Here
> dmd evaluates the second (nested) static if before the first one:
>
> static if (S.a) static assert (S.a);
>
> struct S {
> static if (true) const bool a = true;
> }
>
Yes; DMD is buggy and the specification is insufficient. Currently the
meaning of D code as interpreted by DMD may depend on the order the
modules are passed to the compiler on the command line.
>> An algorithm has been discussed which would remove that restriction;
>> your example would then compile. It's difficult to implement though.
>> It has to deal with paradoxes:
>>
>> static if (!is(typeof(x)) int y = 1;
>> static if (!is(typeof(y)) int x = 1;
>>
>> Who wins?
>
> Nice example! Shouldn't the compiler report errors when it detects kind
> of 'circular dependency' between the names occurring in static if
> conditions and the ones declared in their bodies?
>
> Artur
>
Indeed, the above code should not compile. My upcoming D front end
currently reports the following after fixing the grammatical mistakes
(For now. The error message text should maybe be improved. Ideas welcome.)
tt.d:2:32: error: declaration of 'x' smells suspiciously fishy
static if (!is(typeof(y))) int x = 1;
^
tt.d:1:23: note: this lookup should have succeeded if it was valid
static if (!is(typeof(x))) int y = 1;
^
tt.d:1:32: error: declaration of 'y' smells suspiciously fishy
static if (!is(typeof(x))) int y = 1;
^
tt.d:2:23: note: this lookup should have succeeded if it was valid
static if (!is(typeof(y))) int x = 1;
^
There are lots of similar analysis order issues without static if.
(Luckily, they can be detected well enough conservatively in a quite
general way.) The following is a simplified example from my test suite:
class A{ int string; }
template Mixin(string s){
mixin("alias "~s~" Mixin;");
}
class D: Mixin!({D d = new D; return d.foo();}()){
int foo(int x){ return 2;}
string foo(){ return "A"; }
}
The problem is of course that 'string' has to be resolved in order to
compute the parent of 'D'. However, that parent then changes the meaning
of 'string' in the subclass scope. Therefore, the code is meaningless.
Apparently, this currently crashes DMD (segmentation fault).
bug.d:1:14: error: declaration of 'string' smells suspiciously fishy
class A{ int string; }
^~~~~~
bug.d:7:5: note: this lookup on subclass 'D' should have succeeded if it
was valid
string foo(){ return "A"; }
^~~~~~
More information about the Digitalmars-d
mailing list