extern(C++, ns)

Carl Sturtivant via Digitalmars-d digitalmars-d at puremagic.com
Wed Jan 6 08:21:17 PST 2016


On Wednesday, 6 January 2016 at 05:14:30 UTC, Carl Sturtivant 
wrote:
>
> OK, I'm going to state the obvious here in the hope it will be 
> considered afresh. :)
>
> On Sunday, 3 January 2016 at 17:53:38 UTC, Walter Bright wrote:
>> 5. I don't share the opinion that a C++ namespace introducing 
>> a scope, just as it does in C++, is something weird and 
>> unexpected.
>
> Wait a second: D has modules with clever import rules and no 
> global scope to manage name collisions instead of namespaces. 
> See the bullet here under "features to drop from C++":
> http://dlang.org/overview.html#features_to_drop
>
> What's now going on is the reintroduction of this dropped 
> feature in a way that is at cross purposes to the underlying D 
> language philosophy.
>
> In the end the disputed difficult comes down to this:
>     extern(C++, ns1) int fn(int x);
> and
>     extern(C++, ns2) int fn(int x);
> have different mangled names but the same D-source name. They 
> also have the same C++ source name.
>
> In the C++ source this collision is averted by namespaces. In 
> the D source where the namespace mechanism has been designed 
> out in favor of the module mechanism, this collision should be 
> averted using the module mechanism.
>
> If you still believe you want to be able to place the colliding 
> externals in the same module, i.e. not use D's collision 
> avoidance mechanism, what's needed is simply the ability to 
> have two different D source names for the two functions 
> specified in the two declarations. This is just a name change, 
> not an entire new scope with all the complexity that would 
> entail in the namespace situation.
>
> Perhaps there's a way to do this in D already: how do you link 
> to a C function whose name is 'new' or some other D keyword?
>
> In any case, drawing a distinction between the D source name 
> and the C++ source name (or the external source name in 
> general) in the external declaration would do the job. e.g.
>
> extern(C++, ns1, fn) int fn1(int x);
> extern(C++, ns2, fn) int fn2(int x);
>
> In each case the external declaration has enough information to 
> compute the mangled name and attach it to a D source name 
> without collision.
>
> My opinion: Injecting C++ bad design into D in the name of 
> linkage is wrong, ugly, and over complicated. I don't think the 
> alternative mechanism suggested in the preceding paragraph or 
> anything similar is necessary either, since D modules are the 
> replacement for namespaces in going from C++ to D, and they can 
> do the job. But something like that alternative is a lot less 
> awful.

A clean design for external C++ linkage that handles namespaces 
could simply involve extending #pragma(mangle,.......) to take a 
quoted namespace. This keeps extern() simple as a purely 
linkage/mangling related qualification, as expected, with no 
extra scope simulating a namespace being introduced.

A name collision in the existing machinery,
     extern(C++,ns1) int fn(int x);
     extern(C++,ns2) int fn(int x);
could instead be a compiler error, and be averted by e.g. the 
following new mechanism.

#pragma(mangle, "fn", "ns1")
extern(C++) int fn1(int x);

#pragma(mangle, "fn", "ns2")
extern(C++) int fn2(int x);

Maybe the C++ namespace's name could be permitted either quoted 
in the pragma as above (so that names that are D keywords can be 
accommodated) or implicitly taken up by the pragma from the 
external declaration as in the following.

#pragma(mangle, "fn")
extern(C++, ns1) int fn1(int x);

#pragma(mangle, "fn")
extern(C++, ns2) int fn2(int x);

Of course most of the time this wouldn't be used, because the 
offending declarations can be placed in different D modules. So 
then linkage to C++ is handled like linkage to C, simply!




More information about the Digitalmars-d mailing list