Why version() ?

Steven Schveighoffer schveiguy at yahoo.com
Tue Feb 10 13:44:12 PST 2009


"Walter Bright" wrote
> bobef wrote:
>> I was thinking... what is the point of version() ? It is so
>> inflexible. There is no even version(!...). Why not "static
>> if(version(DMD))" or static if(is(version == DMD))?
>
> The version statement is designed to be inflexible. It's designed to 
> encourage abstracting and modularizing version differences, rather than 
> encouraging line-by-line differences.
>
> I've used #if/#endif for decades. Over time, it *always* degenerates into 
> an utter rat's nest of nested, incomprehensible complexity (and this 
> includes my own code). For a lovely example of how bad it can get, take a 
> look at the source code to Hans Boehm's garbage collector. I defy anyone 
> to figure it out without running the code through the preprocessor first 
> to see which statements are actually getting compiled.

There can exist a happy medium between the rigid current design and the 
disaster that is #if.

> 2. version (A || B) can be done as:
>
>     version (A) version=AorB;
>     version (B) version=AorB;

And it would be much nicer NOT to have to do this.  I think your original 
position of "let's not get into #if hell" has absolutely (and I mean 
*absolutely*) no merit as an argument against this one change.

Think of code that is versioned around architecture that would look 
horrendous if you have to do version statements that have all different 
combinations of stuff.  If I have 5 different architectures to support, I 
don't want to have to define a module that has 2^5 different version 
combinations.  On top of that, the way versioning works, you need 2^4 * 5 
different statements:

version(A)
{
   version = AorB;
   version = AorC;
   version = AorD;
   version = AorE;
   version = AorBorC;
   version = AorBorD;
   // ad nauseum.
}
version(B)
{
   // oh fun! let's do it again!!!!
   version = AorB;
   version = BorC;
   version = BorD;
   ...
}

When I add another architecture, *gasp* I have to double the statements (to 
do them now with and without version(F) ), and now I have to do another 2^5 
statements for the version(F) block.  Wheee!

Add to this nightmare that I have to worry about syntax errors, or doing 
stupid shit like:

version(BorA) // whoops, it's spelled AorB stupid!  no compiler error given

All this can be reduced to 0 statements, and 0 headache if the logical || 
can be used.  This is why we have computers, so we don't have to calculate 
this stuff.  Please don't make me use my brain and typing skills where a 
computer is soooo much better.

>
> 3. version (A && B) can be done as:
>
>    version (A) version (B) { ... }

This isn't as bad of a problem as ||, but still could be nicer as the 
suggested && syntax.  But I'd be ok with having just the ||.

> 5. Why can't one 'version out' syntax that is not recognized by the 
> compiler?
>
> The problem is that supporting this requires semantic analysis in order to 
> successfully lex and parse the source code. Breaking this will make the 
> lexing and parsing an order of magnitude harder for third party tools to 
> do. If you need to 'comment out' a section of syntactically invalid code, 
> use the /+ ... +/ nesting comment.

Just so you know, this is not a solution.  We all know that the main reason 
people ask for this is to have code that can compile with D1 or D2 using 
versioning.  /+ .. +/ doesn't help there.

-Steve 





More information about the Digitalmars-d mailing list