D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 5739 - versioned linkage declarations don't work
Summary: versioned linkage declarations don't work
Status: RESOLVED INVALID
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: All All
: P2 normal
Assignee: No Owner
URL:
Keywords: accepts-invalid, rejects-valid, wrong-code
Depends on:
Blocks:
 
Reported: 2011-03-15 04:51 UTC by Trass3r
Modified: 2015-06-09 05:11 UTC (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Trass3r 2011-03-15 04:51:51 UTC
main.d:
=======
import versionextern;

void main()
{
	foo();
}

versionextern.d:
================
version = Bla;

version(Bla)
{
	extern(Windows):
}
else version(Blub)
{
	extern(C):
}
void foo();

yields:
Symbol Undefined _D13versionextern3fooFZv
no matter what version is defined.

removing the parentheses and else:
version(Bla)
	extern(Windows):
version(Blub)
	extern(C):

even results in:
main(5): Error: undefined identifier foo


I'm not sure if this is a rejects-valid or accepts-invalid issue.
Comment 1 Jacob Carlborg 2011-03-15 05:47:14 UTC
In this particular case you could use "extern (System)". But this should probably be fixed anyway.
Comment 2 Trass3r 2011-03-15 10:06:21 UTC
Yep I know, but the original code is like:

version(CL_VERSION_1_1)
    extern(System):
else
    extern(C):
Comment 3 Walter Bright 2011-03-15 11:34:16 UTC
This is not a bug. A linkage declaration that ends in ':' runs to the end of the block, which in this case is the end of the version declaration.
Comment 4 Jacob Carlborg 2011-03-15 12:30:42 UTC
But how does he get "Error: undefined identifier foo"? Shouldn't "foo" just be declared as a regular function?
Comment 5 Trass3r 2011-03-18 02:45:55 UTC
Yep, the second issue still persists.

I found out what I originally wanted to do can be achieved via:

extern(C):
version(Bla)
    extern(Windows): // though replacing this with mixin("extern(Windows):"); doesn't work, then extern(C) wins
void foo();


But as soon as you have 2 blocks like 

version(Bla)
    extern(Windows):
version(Blub)
    extern(C++):

and Blub isn't set, it fails with "undefined identifier foo"
Comment 6 Trass3r 2011-03-18 02:57:13 UTC
Ah never mind, turns out it doesn't work.

extern(C):
version(Bla)
    extern(Windows):
void foo();

fails as soon as Bla isn't defined. I guess it has to do with the parser.

Because of the ':' it probably gets read like:

version(Bla)
{
    extern(Windows):
    void foo();
}
Comment 7 Walter Bright 2012-01-20 18:57:36 UTC
(In reply to comment #4)
> But how does he get "Error: undefined identifier foo"? Shouldn't "foo" just be
> declared as a regular function?

It gets parsed like:

    extern(C): void foo();

and so foo is undefined.