Is there any good reason why C++ namespaces are "closed" in D?

Atila Neves atila.neves at gmail.com
Fri Aug 3 10:58:18 UTC 2018


On Wednesday, 1 August 2018 at 23:31:57 UTC, Walter Bright wrote:
> On 7/31/2018 1:47 AM, Atila Neves wrote:
>> The only good way (I don't think the mixin template and struct 
>> solutions count) to link to any of that today would be to have 
>> one enormous D file with _everything_ in it, including nested 
>> namespaces.
>
> Why doesn't it count? The user doesn't need to write that code, 
> the translator does. It achieves what you ask for - a 
> declaration of foo() in the current scope, with the mangling in 
> the C++ namespace.

Good point.

I thought about it some more and managed to make it work. It's 
definitely a hack, but since in my case the user won't usually 
see the generated code anyway it's not too bad. It's far from 
ideal, though, because I can't alias an entire nested namespace 
if it's declared twice, i.e.

namespace std {
    namespace chrono {
       // ...
    }
}

namespace std {
     namespace chrono {
     }
}

With your mixin template technique everything ends up in the 
global namespace of the moduel making the C++ declarations. I 
would only be able to alias a nested namespace once, since the 
code below obviously won't work:

    mixin CppNamespace0!() x;
    alias chrono = x.std.chrono;
    mixin CppNamespace1!() y;
    alias chrono = y.std.chrono;

I considered for a while whether or not this would be truly bad, 
and the more I think about it the more convinced I am that Manu 
is right and there should be _no_ scoping whatsoever in D 
regarding C++ namespaces. We have packages and modules, we can 
use those to put the C++ functions we declare in whatever 
hierarchy we want.

I think that this:

> It's where std::exception goes -> core.stdcpp.exception
> In it, you'll find some extern(C++,std) declarations. The file 
> can be imported as:
>    import core.stdcpp.exception;
> or:
>    import core.stdcpp.exception : std;

    shouldn't even come up, by which I mean `std` should never be 
part of the fully qualified name of, for instance, 
`core.stdcpp.exception.std.bad_exception`. It should just be 
`core.stdcpp.exception.bad_exception` instead. If one wants to 
create a `core.stdcpp.chrono`, then it's a case of putting 
`extern(C++, std.chrono)` in that module and mirroring the 
namespace hierarchy manually. I don't think the extra `std` helps 
in any way right now, and anyone writing C++ declarations 
manually has to go through all the trouble of setting up aliases.

None of the warts of C++ scope contaminate D this way. Nobody 
will ever need to know what ADL is. D scoping and overload rules 
would be applied, and `extern(C++)` declarations with namespaces 
only mangle.

It would be a breaking change. However, I'd be willing to bet 
real money that anybody that cares about linking to C++ would 
gladly see their code break because they're probably using 
workarounds anyway.

Atila


More information about the Digitalmars-d mailing list