Thread overview | |||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
March 28, 2013 In what order static if conditions are evaluated? | ||||
---|---|---|---|---|
| ||||
Hi, DMD (I'm using v2.060) seems to evaluate conditions in static if's from top to bottom (at least in a given scope). For example, consider the following program: module test; const bool x = true; const bool y = true; struct S { static assert(y); static if(x) static const bool y = false; static if(y) static const bool x = false; } 'x' in the first static if condition refers to .x and the static if introduces S.y to which 'y' in the second static if refers. 'y' in the static assert also refers to S.y and thus the assertion fails: test.d(8): Error: static assert (y) is false Now, I guess if the second static if were evaluated first then 'y' in the static assert condition would refer to .y and the program would compile. Note that dmd evaluates the static assert *after* both static if's. So clearly D program semantics depends on the order static if's and static assert's are evaluated. Are there any standard rules here (I cannot find anything in Language Reference) or is this behaviour implementation dependent? Artur |
March 28, 2013 Re: In what order static if conditions are evaluated? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Artur Zawłocki | On 03/28/2013 06:29 AM, "Artur Zawłocki" <artur.zawlocki@gmail.com>" wrote:
> Hi,
>
> DMD (I'm using v2.060) seems to evaluate conditions in static if's from
> top to bottom (at least in a given scope). For example, consider the
> following program:
>
> module test;
>
> const bool x = true;
> const bool y = true;
>
> struct S {
>
> static assert(y);
>
> static if(x)
> static const bool y = false;
>
> static if(y)
> static const bool x = false;
> }
>
> 'x' in the first static if condition refers to .x and the static if
> introduces S.y to which 'y' in the second static if refers. 'y' in the
> static assert also refers to S.y and thus the assertion fails:
>
> test.d(8): Error: static assert (y) is false
>
> Now, I guess if the second static if were evaluated first then 'y' in
> the static assert condition would refer to .y and the program would
> compile. Note that dmd evaluates the static assert *after* both static
> if's.
>
> So clearly D program semantics depends on the order static if's and
> static assert's are evaluated. Are there any standard rules here (I
> cannot find anything in Language Reference) or is this behaviour
> implementation dependent?
>
> Artur
It should behave the "same" as a normal if statement.
Except it is evaluated during compile-time and not runtime.
The only different that I know of is that the brackets will not introduce a new scope.
string Y;
if(true) {
string x = "I'm not in the same scope as Y";
}
static if(true) {
string z = "but I am";
}
that's the only "gotcha" I know of, and I seems quite intuitive once you realize why that is the case.
But I can't think of any reason why a compiler would want to mix up the static if's.... Sounds malicious to me. =P
|
March 28, 2013 Re: In what order static if conditions are evaluated? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Artur Zawłocki | On Thursday, 28 March 2013 at 11:29:49 UTC, Artur Zawłocki wrote:
> Hi,
>
> DMD (I'm using v2.060) seems to evaluate conditions in static if's from top to bottom (at least in a given scope). For example, consider the following program:
>
> module test;
>
> const bool x = true;
> const bool y = true;
>
> struct S {
>
> static assert(y);
>
> static if(x)
> static const bool y = false;
>
> static if(y)
> static const bool x = false;
> }
>
> 'x' in the first static if condition refers to .x and the static if introduces S.y to which 'y' in the second static if refers. 'y' in the static assert also refers to S.y and thus the assertion fails:
>
> test.d(8): Error: static assert (y) is false
>
> Now, I guess if the second static if were evaluated first then 'y' in the static assert condition would refer to .y and the program would compile. Note that dmd evaluates the static assert *after* both static if's.
>
> So clearly D program semantics depends on the order static if's and static assert's are evaluated. Are there any standard rules here (I cannot find anything in Language Reference) or is this behaviour implementation dependent?
>
> Artur
Yes, it currently evaluates it top to bottom. 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?
|
March 28, 2013 Re: In what order static if conditions are evaluated? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Don | On Thursday, 28 March 2013 at 11:52:26 UTC, Don wrote:
> On Thursday, 28 March 2013 at 11:29:49 UTC, Artur Zawłocki wrote:
>> Hi,
>>
>> DMD (I'm using v2.060) seems to evaluate conditions in static if's from top to bottom (at least in a given scope). For example, consider the following program:
>>
>> module test;
>>
>> const bool x = true;
>> const bool y = true;
>>
>> struct S {
>>
>> static assert(y);
>>
>> static if(x)
>> static const bool y = false;
>>
>> static if(y)
>> static const bool x = false;
>> }
>>
>> 'x' in the first static if condition refers to .x and the static if introduces S.y to which 'y' in the second static if refers. 'y' in the static assert also refers to S.y and thus the assertion fails:
>>
>> test.d(8): Error: static assert (y) is false
>>
>> Now, I guess if the second static if were evaluated first then 'y' in the static assert condition would refer to .y and the program would compile. Note that dmd evaluates the static assert *after* both static if's.
>>
>> So clearly D program semantics depends on the order static if's and static assert's are evaluated. Are there any standard rules here (I cannot find anything in Language Reference) or is this behaviour implementation dependent?
>>
>> Artur
>
> Yes, it currently evaluates it top to bottom. 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?
Current already have to deal with paradoxes.
|
March 28, 2013 Re: In what order static if conditions are evaluated? | ||||
---|---|---|---|---|
| ||||
Posted in reply to 1100110 | On Thursday, 28 March 2013 at 11:50:58 UTC, 1100110 wrote: > On 03/28/2013 06:29 AM, "Artur Zawłocki" <artur.zawlocki@gmail.com>" wrote: >> Hi, >> >> DMD (I'm using v2.060) seems to evaluate conditions in static if's from >> top to bottom (at least in a given scope). For example, consider the >> following program: >> >> module test; >> >> const bool x = true; >> const bool y = true; >> >> struct S { >> >> static assert(y); >> >> static if(x) >> static const bool y = false; >> >> static if(y) >> static const bool x = false; >> } >> >> 'x' in the first static if condition refers to .x and the static if >> introduces S.y to which 'y' in the second static if refers. 'y' in the >> static assert also refers to S.y and thus the assertion fails: >> >> test.d(8): Error: static assert (y) is false >> >> Now, I guess if the second static if were evaluated first then 'y' in >> the static assert condition would refer to .y and the program would >> compile. Note that dmd evaluates the static assert *after* both static >> if's. >> >> So clearly D program semantics depends on the order static if's and >> static assert's are evaluated. Are there any standard rules here (I >> cannot find anything in Language Reference) or is this behaviour >> implementation dependent? >> >> Artur > > It should behave the "same" as a normal if statement. Why? static if is not a statement at all, it's a 'conditional declaration'. And the order in which declarations are processed on the top level is not relevant (unless you have static if's, that is), e.g. you can have: static if (a) static assert (true); const bool a = true; I've just discovered that this is also OK: static if (S.a) static assert (true); struct S { static if if (true) const bool a = true; } |
March 28, 2013 Re: In what order static if conditions are evaluated? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Don | 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; } > 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 |
March 28, 2013 Re: In what order static if conditions are evaluated? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Artur Zawłocki | On 03/28/2013 08:15 AM, "Artur Zawłocki" <artur.zawlocki@gmail.com>" wrote:
> On Thursday, 28 March 2013 at 11:50:58 UTC, 1100110 wrote:
>> On 03/28/2013 06:29 AM, "Artur Zawłocki" <artur.zawlocki@gmail.com>"
>> wrote:
>>> Hi,
>>>
>>> DMD (I'm using v2.060) seems to evaluate conditions in static if's from
>>> top to bottom (at least in a given scope). For example, consider the
>>> following program:
>>>
>>> module test;
>>>
>>> const bool x = true;
>>> const bool y = true;
>>>
>>> struct S {
>>>
>>> static assert(y);
>>>
>>> static if(x)
>>> static const bool y = false;
>>>
>>> static if(y)
>>> static const bool x = false;
>>> }
>>>
>>> 'x' in the first static if condition refers to .x and the static if
>>> introduces S.y to which 'y' in the second static if refers. 'y' in the
>>> static assert also refers to S.y and thus the assertion fails:
>>>
>>> test.d(8): Error: static assert (y) is false
>>>
>>> Now, I guess if the second static if were evaluated first then 'y' in
>>> the static assert condition would refer to .y and the program would
>>> compile. Note that dmd evaluates the static assert *after* both static
>>> if's.
>>>
>>> So clearly D program semantics depends on the order static if's and
>>> static assert's are evaluated. Are there any standard rules here (I
>>> cannot find anything in Language Reference) or is this behaviour
>>> implementation dependent?
>>>
>>> Artur
>>
>
>> It should behave the "same" as a normal if statement.
>
> Why? static if is not a statement at all, it's a 'conditional
> declaration'. And the order in which declarations are processed on the
> top level is not relevant (unless you have static if's, that is), e.g.
> you can have:
>
> static if (a)
> static assert (true);
>
> const bool a = true;
>
> I've just discovered that this is also OK:
>
> static if (S.a)
> static assert (true);
>
> struct S { static if if (true) const bool a = true; }
>
Ah! I see what you're getting at.
I had just assumed getting it right was up to us. =P
|
March 28, 2013 Re: In what order static if conditions are evaluated? | ||||
---|---|---|---|---|
| ||||
Posted in reply to deadalnix | On 03/28/2013 07:04 AM, deadalnix wrote:
> On Thursday, 28 March 2013 at 11:52:26 UTC, Don wrote:
>> On Thursday, 28 March 2013 at 11:29:49 UTC, Artur Zawłocki wrote:
>>> Hi,
>>>
>>> DMD (I'm using v2.060) seems to evaluate conditions in static if's
>>> from top to bottom (at least in a given scope). For example, consider
>>> the following program:
>>>
>>> module test;
>>>
>>> const bool x = true;
>>> const bool y = true;
>>>
>>> struct S {
>>>
>>> static assert(y);
>>>
>>> static if(x)
>>> static const bool y = false;
>>>
>>> static if(y)
>>> static const bool x = false;
>>> }
>>>
>>> 'x' in the first static if condition refers to .x and the static if
>>> introduces S.y to which 'y' in the second static if refers. 'y' in
>>> the static assert also refers to S.y and thus the assertion fails:
>>>
>>> test.d(8): Error: static assert (y) is false
>>>
>>> Now, I guess if the second static if were evaluated first then 'y' in
>>> the static assert condition would refer to .y and the program would
>>> compile. Note that dmd evaluates the static assert *after* both
>>> static if's.
>>>
>>> So clearly D program semantics depends on the order static if's and
>>> static assert's are evaluated. Are there any standard rules here (I
>>> cannot find anything in Language Reference) or is this behaviour
>>> implementation dependent?
>>>
>>> Artur
>>
>> Yes, it currently evaluates it top to bottom. 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?
>
> Current already have to deal with paradoxes.
Does the current *implementation* have to deal with paradoxes, or do the current *users*? =P
But no serious question. I'm curious.
|
March 28, 2013 Re: In what order static if conditions are evaluated? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Artur Zawłocki | On 03/28/2013 02:34 PM, "Artur Zawłocki" <artur.zawlocki@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"; } ^~~~~~ |
March 28, 2013 Re: In what order static if conditions are evaluated? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Don | On 03/28/2013 12:52 PM, Don wrote: > ... > > Yes, it currently evaluates it top to bottom. An algorithm has been > discussed which would remove that restriction; I'm not sure that restriction is the correct word. There is not always a well-defined top-to-bottom order. > your example would then compile. It's difficult to implement though. It was rather easy to implement. Do you mean it might be hard to fit it into the existing DMD code base? > It has to deal with paradoxes: > > static if (!is(typeof(x)) int y = 1; > static if (!is(typeof(y)) int x = 1; > > Who wins? > Nobody. :o) |
Copyright © 1999-2021 by the D Language Foundation