extern(C++, NS)

Manu via Digitalmars-d digitalmars-d at puremagic.com
Sat Nov 28 21:17:06 PST 2015

On 29 November 2015 at 14:57, Walter Bright via Digitalmars-d
<digitalmars-d at puremagic.com> wrote:
> 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.

Then the feature fails. You can't put the entire STL in one file.
C++ doesn't namespace per file, it generally namespaces per project...
so this is the common case; every module define symbols in the same
C++ namespace.

>> 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.

I understand, and that's fine, but it's not particularly useful unless
I can make the namespace invisible and alias the namespaced symbols
into D's module (user-accessible) scope. Otherwise importing 2 modules
leads to conflicting namespace and symbol resolution is all messed up.

>> 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.

Maybe a special case for C++ namespaces? Or some other solution that
produces the same result.
It's a weird sort of permission this one, it's not that the symbols
are 'private'; I intend the user to use them, I just want the C++
hierarchy excluded from the symbol table and only accessibly by
controlled/explicit alias.

>> 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.

I don't think I'm doing that at all, I'm just trying to make some C++
code linkable to D, and it doesn't work at all.
I think you misunderstood my entire post, I don't want C++ semantics
at all, I just want to mangle like C++ for linkage, but the
implementation doesn't let me do that. If anything, I'm trying to make
C++ extern's behave like D semantics, but namespaces aren't a normal
part of D, and don't really have idioms for dealing with this.

C++ tends to namespace everything with the same namespace, and that
means either I implement the entire C++ library in a single module (no
way), or I face this mess. The feature just doesn't work beyond a
single file linkage experiment, or I completely missed how I'm
supposed to use it.

More information about the Digitalmars-d mailing list