version and extern problems

torhu fake at address.dude
Sun Jul 8 10:10:31 PDT 2007


Walter Bright wrote:
> > 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; }

I don't like any of these solutions.  This is so straight forward with
the C preprocessor.  Even using the future macro feature means
duplicating definitions.

AFAIK, these problems only affect the linkage attributes, meaning
extern (C), extern (Windows), and export.

If Mike Wey's string mixin solution is allowed in future dmd versions, I
guess the situation isn't that bad.  As long as bug 1306 is fixed, anyway.

Another way would be to accept that this is a special case that needs a
pragmatic solution, and expand the syntax a bit:

extern (Windows, C):

According to the docs, A D compiler only need to support Windows and
Pascal conventions on Windows.  So on other platforms, the compiler
could just pick the first valid linkage for that platform.  A version ID
could be incorporated too, if there's ever a need for it:

extern (Windows : Windows; WeirdPlatform: WeirdLinkage; C):


The problem with 'export' is related.  I wonder if something similar
could work for that.  Make it conditional somehow:

export (DLLVERSION) int someVar;
export (version DLLVERSION) int someVar;
version (DLLVERSION)(export) int someVar;

The third version has the advantage of being applicable to other cases too:

version (Windows) (extern (Windows)) else (extern (C)) {
     /* openGL prototypes */
}


I don't know if this syntax is feasible, I'll leave that to the experts. 
  :)



More information about the Digitalmars-d mailing list