"Nick Sabalausky" <a...@a.a> wrote in message 
news:i9ldub$f7...@digitalmars.com...
> "Jesse Phillips" <jessekphillip...@gmail.com> wrote in message 
> news:i9l935$5u...@digitalmars.com...
>> bearophile Wrote:
>>
>>> If built-in versions are inside some kind of enum or namespace, the 
>>> compiler can tell apart the built-in ones from all the other ones, so if 
>>> you write:
>>> version(std.D_Inline_Asm_X86_65)
>>> The compiler will complain that doesn't exists among the standard ones.
>>>
>>> If you want to use your own ones you just don't use the "std." prefix:
>>> version(myFoo)
>>>
>>> Bye,
>>> bearophile
>>
>> Note that the latest highlighting file for Vim will highlight the known 
>> built-in version Identifiers.
>>
>> I don't have much of a suggestion for solving the real issue, but maybe 
>> the compiler could return a list of versions used? Though that brings to 
>> question what happens to versions used in side versions.
>
> Clearly, the current version system is a suboptimal design. Unfortunately, 
> given the specific nature of it, it doesn't appear to be possible work 
> around this particular issue. And I don't think it's possible to sidestep 
> it with a library-based alternative either, due to D's apperent inability 
> to have deterministic cross-module global mutable state at compile time 
> (see the thread "[challenge] Limitation in D's metaprogramming").
>
> So I think aside from a pre-processor, the only real way to solve this 
> issue is to redesign the version system to not work on a basis of 
> "defined/not defined". I would certainly be in favor of that, but I 
> suspect it would probably mean a D3 (or at least a D2.5 - "@version" 
> anyone?).
>
> Although, here's another idea that might at least help (athough not nearly 
> as cleanly as a redesigned version system):
>
> There could be a "__traits(allVersionIdents)" that returns an array of all 
> identifiers that are actually used anywhere in the program, *even* ones 
> that turn out to be undefined. Or maybe a __traits that returns *just* the 
> version identifiers that are used but undefined. This list is logically 
> (if not physically) built up *before* any "version{}", "debug{}", or 
> "static if" conditionals are actually evaluated (but after any string 
> mixins, so that might be tricky, if even possible). Then, you can validate 
> that list against all of the identifiers that you expect to possibly be 
> used. There would also be a "__traits(builtinVersionIdents)" to aid with 
> this.
>

Now that I think of it, it might not even be necessary for the list of 
used-but-undefined version identifiers to be built up before 
"version"/"static if"-etc is evaluated:

version(Windows)
{
    version(Oops_This_One_Is_A_Typo)
}

void main()
{
    string[] allPossibleVersions = [/+...+/];
    assert(/+ __traits(allVersionIdents) is a subset of allPossibleVersions 
+/);
}

Compiling for Linux will fail to catch the version typo. However, clearly 
the code is intended to occasionally be compiled for windows, and when it 
does you'll be able to detect that "Oops_This_One_Is_A_Typo" is misspelled.

But what if "version(Windows)" is misspelled as "Widnoes" which causes 
"Oops_This_One_Is_A_Typo" to *never* be in the __traits(allVersionIdents) 
list? No problem: You'll catch the "Widnoes" error anyway no matter how it's 
compiled, and once you fix that, then you'll get the error with 
"Oops_This_One_Is_A_Typo".

So I think this could work.

The only tricky thing I see with whole approach is: what to do about 
libraries that have their own set of possible version identifiers? That 
would require some extra thought, but I don't think it's insurmountable.


Reply via email to