Does D allow paradoxical code?

Rainer Schuetze r.sagitario at gmx.de
Sat Mar 27 07:54:52 PDT 2010


With the patch in bugzilla #461 ( 
http://d.puremagic.com/issues/show_bug.cgi?id=461 ) applied, you get the 
  expected output:

test.d(1): Error: version v1 defined after use
no

version and debug conditions are analyzed and expanded before any other 
semantic analysis in a module. I think, versions are defined and limited 
enough, so you get what you can expect.

But your point holds, if you replace version in your example with static 
if conditions. These need semantic analysis and this is done (mostly) in 
lexical order. A forward reference to an identifier defined inside the 
static if fails, because the identifiers inside a static if are only 
known in the given scope after evaluating the condition. There are also 
entries to that effect in bugzilla (e.g. 
http://d.puremagic.com/issues/show_bug.cgi?id=3743 ) Even worse, 
declarations inside a static if can change an overload-set, so you might 
not get an error, but unexpected calls that are very hard to track down.

Similar problems can occur with mixins. I'm not sure CTFE falls into the 
same category, as it does not generate declarations by itself, it helps 
evaluating conditions or strings for mixins.

Here's my current guess, how to allow forward references in most cases: 
when the compiler "visits" a scope (module, class, etc.) due to normal 
semantic analysis or identifier lookup, compile-time conditions and 
mixins at the same nesting-level must be evaluated *before anything 
else* in this scope. A static if condition or mixin must not reference 
an identifier declared inside a condition or mixin later.

Rainer

Jerry Quinn wrote:
> What should happen when the following code is compiled?
> 
> mixin(vs);
> version(v1) {
>   const string vs = "version = v2;";
>   pragma(msg, "yes");
> }
>  else {
>   const string vs = "version = v1;";
>   pragma(msg, "no");
>  }
> 
> Currently, there's an error saying that vs must be a string.  However, as far as I can tell, the spec says nothing about order affecting module-scope declarations.  So vs should be valid, and once it substitutes in the mixin, you have a cycle where no matter what vs is, vs should be the other value.
> 
> If you don't have the conditional compilation and put the declaration of vs after the mixin, it works as expected.
> 
> This generally raises the question of what should be the order of evaluation for constructs like mixins, conditional compilation, and CTFE.   Each has the potential to modify the other.
> 
> What should be the rule to break the ambiguity?  Or do we leave it implementation-defined?
> 
> Thoughts?
> Jerry



More information about the Digitalmars-d mailing list