version and extern problems
Walter Bright
newshound1 at digitalmars.com
Sat Jul 7 19:21:01 PDT 2007
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