extern(C++, NS)

Walter Bright via Digitalmars-d digitalmars-d at puremagic.com
Sat Nov 28 20:57:40 PST 2015


On 11/28/2015 8:40 PM, Manu via Digitalmars-d wrote:
> I'm having a lot of trouble with C++ namespaces.
> The problem is, the namespace is not just attributed to the symbol in
> D, but it's emulated as a named scope.

It is not "emulated" in D, it is an actual named scope in D.


> The trouble mostly appears in this situation:
>
> file1.d
>    extern(C++, NS) struct X;
>
> file2.d
>    extern(C++, NS) struct Y;
>
> file3.d
>    import file1, file2;
>    X x; // nope
>    Y y; // nope
>    NS.X x; // NS has multiple definitions...
>    NS.Y y; // NS has multiple definitions...
>
>
> And various other configurations similar to this where multiple files
> declare symbols in the same C++ namespace, and then something tries to
> import more than one of them.
> Circular imports of this sort always cause problems.

D does not support C++ semantics. You cannot split namespaces into multiple 
files in D, nor can you add symbols to an existing namespace. For namespace NS, 
all the declarations in NS have to be in one file and between the { }, just like 
any other scope in D.


> Additionally to that, I don't really want the C++ namespaces to be
> visible to D; they should be for mangling purposes only.

We considered making them for mangling only, and rejected it as unworkable, 
because then two identical names in different namespaces could not be 
distinguished by the D symbol table system.


> So I try code like this:
>    private extern(C++, NS) struct Thing {}
>    alias Thing = NS.Thing;
>
> The idea being that NS will not be available externally, and they
> should use Thing in module scope instead, but that doesnt work with
> errors:
>    Error: module blah class blah.NS.Thing is private
>
> It seems aliasing a private thing into the public namespace does not
> make it accessible via that alias?

Aliases do not change access permissions. They are just aliases.


> The only way I've managed to make any of those work is with proxy
> modules, which static import the C++ module, and then `alias Thing =
> NS.Thing` into the proxy module's scope. This is horrid, and it
> doubles my module count. I haven't found another pattern that's
> reliably workable.
>
> Ideas?

Stop trying to bash D into behaving like C++! It'll just make for horrid code 
(as you discovered) and make you miserable trying. D has an interface to C++; it 
does not have C++ semantics.



More information about the Digitalmars-d mailing list