version and extern problems

Russell Lewis webmaster at villagersonline.com
Sun Jul 8 14:25:03 PDT 2007


This sounds like the perfect place for alias, or something like it.  The 
idea would be to write code like this:

--------------
version(Windows)
   <do alias declaration here>;
else
   <do other alias delcaration here>;

extern(myAlias) typedef void function() foo;
--------------

Problem is, I haven't yet found a syntax that I like.  I came up with 3 
possibilities:

1) alias extern(Windows) extern(myAlias);

I don't like the extern(mine) part, because it reminds me too much of C 
function pointers.  That was a good example of a nice theoretical syntax 
that never worked in practice, IMHO.

Plus, this syntax could easily be read as "extern(Windows) attribute on 
the type extern(mine)..."  Technically, I guess the grammar's not 
ambiguous, but it's ugly.

2) alias extern(Windows) myAlias;

I don't like how this breaks the parallelism.  Would you use the alias 
extern(myAlias)?  Or would you drop the extern() part around it?  If the 
latter, how would you parse it without ambiguities?

Plus, the same problem as before where it looks like extern(Windows) is 
an attribute on something else.

3) alias Windows myAlias;

I presume that Windows isn't a valid symbol, so this has its own problems.


Thoughts?  About the concept in general, or about a good syntax?

Russ

Walter Bright wrote:
> Bug 1311 http://d.puremagic.com/issues/show_bug.cgi?id=1311
> is about using version declarations to control part of a following 
> declaration (or series of declarations):
> 
> -------------------------
> version(Windows)
>     extern(Windows):
> else
>     extern(C):
> 
> typedef void function() foo;
> --------------------------
> 
> This does not work now, and it was a bug that it ever did appear to 
> work. The issue is that version declarations can only affect entire 
> declarations, not parts of them. An extern statement with a : is 
> implicitly the same as:
> 
> ----------------
> extern(Windows):
> int a;
> int b;
> -----is same as---
> extern(Windows)
> {
>    int a;
>    int b;
> }
> -----------------
> 
> That cannot be split up with a version declaration; it would be like 
> trying to make:
> 
>     version (Windows)
>         int
>     else
>         long
>     x;
> 
> work. The old behavior of dmd contained a serious (unreported) bug where 
> such constructs would cause forward references to behave unpredictably.
> 
> So, the question is how to get the same effect? The alternatives are:
> 
> 1.
> version(Windows)
> {
>     extern(Windows):
>        typedef void function() foo;
> }
> else
> {
>     extern(C):
>        typedef void function() foo;
> }
> 
> Yes, that means doing a cut & paste on the code in the braces. Not 
> thrilling, but it works.
> 
> 2. Stop using extern(Windows). The Windows calling convention is only 
> necessary when a) calling Win32 API functions (which don't exist on 
> Linux anyway) and b) calling someone else's C code that pointlessly and 
> spuriously uses the Windows calling convention, and cannot be fixed.
> There is no reason in new C/C++ code to ever use the Windows calling 
> convention.
> 
> 3. Create two source files, one for the extern(Windows) and the other 
> for the extern(C). Have your makefile automatically copy one to the 
> other, using sed to edit that one line. Import one under Windows, the 
> other under Linux.
> 
> 4. Wait for the future 2.0 macro feature, which should be able to deal 
> with this nicely:
> 
> macro Foo()
> {
>     typedef void function() foo;
> }
> version(Windows)
> {   extern(Windows): Foo(); }
> else
> {    extern(C): Foo(); }
> 
> 5. Do the same as (4) using string mixins:
> 
> const string Foo =
> "
>     typedef void function() foo;
> ";
> version(Windows)
> {   extern(Windows): mixin(Foo); }
> else
> {    extern(C): mixin(Foo); }
> 
> 
> 6. Use template mixins:
> 
> template Foo()
> {
>     typedef void function() foo;
> }
> version(Windows)
> {   extern(Windows): mixin Foo; }
> else
> {    extern(C): mixin Foo; }



More information about the Digitalmars-d mailing list