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