extern(C++, NS)

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


On 29 November 2015 at 14:54, Manu <turkeyman at gmail.com> wrote:
> On 29 November 2015 at 14:40, Manu <turkeyman at gmail.com> 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.
>>
>> 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.
>>
>> Additionally to that, I don't really want the C++ namespaces to be
>> visible to D; they should be for mangling purposes only.
>>
>> 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?
>>
>> 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?
>
> Oh yeah, I also tried renamed imports to get the namespaces symbols
> into the module scope, like this:
>   import blah : Thing = NS.Thing;
>
> But that doesn't work.
>
> The extern(C++) docs need to cover these cases and explain how the
> user is supposed to actually use the feature. I'm generally just
> stabbing in the dark :/


Oh yeah, also, C++ namespaces seem to break forward referencing:

Error: identifier 'Thing' of 'NS.Thing' is not defined:
  alias Thing = NS.Thing;
  extern(C++, NS) struct Thing {}


Compiles fine:
  extern(C++, NS) struct Thing {}
  alias Thing = NS.Thing;


More information about the Digitalmars-d mailing list