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

Walter Bright newshound2 at digitalmars.com
Wed Aug 1 10:02:39 UTC 2018


On 7/31/2018 1:12 AM, Manu wrote:
> Given your favourite example:
> ----
> module a;
> extern(C++, ns) void foo();
> ----
> module b;
> extern(C++, ns) void foo();
> -----
> module c;
> import a, b;
> foo(); // error: ambiguous
> ns.foo(); // error, ambiguous (obviously)
> a.ns.foo(); // naturally, this works... it's the D module that
> correctly organises the symbol. 'ns' is worthless here


You can write it like this:

----
module a;
extern(C++, ns) void foo();
alias foo = ns.foo;
----
module b;
extern(C++, ns) void foo();
alias foo = ns.foo;
-----

import a,b;
a.foo();  // calls a.ns.foo()
b.foo();  // calls b.ns.foo()

> When a C++ namespace spans modules (ie, the C++ namespace encloses the
> whole library's api), translation to D looks like this:
> 
> module ns.submodule;
> extern(C++, ns) void foo();
> 
> The name is:
> ns.submodule.ns.foo(); // <- ns is already present at the head of the
> qualified name, there's no point repeating it.

So don't repeat it. There is no particular reason to use that naming convention 
for an ns namespace. As I wrote to Atila, using 'std' as a package name isn't 
going to work very well anyway because it's already used as a root package in 
Phobos.


> The converse case where modules are divided by their namespace (which
> naturally maps to D modules):
> 
> module cpplib.ns;
> extern(C++, ns) void foo();
> 
> Now the name is:
> cpplib.ns.ns.foo(); // <- why would anyone want that?

Why indeed. Don't do that. I don't see any reason to. We've put things like 
string.h in core.stdc.string, and nobody has complained they cannot just type 
"import string;". It works fine. Allow me to refer to:

     https://github.com/dlang/druntime/blob/master/src/core/stdcpp/exception.d

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;

or any of a number of other ways to import it and set up aliases (if one 
prefers) to use as shortcuts to the name.


> But the redundancy is more than a nuisance in certain forms of scanning meta.

As I mentioned, you can use alias to refer to names in other scopes.


> And got forbid the case where C++ namespaces are embedded (namespace
> for lib name, another for the module), and we have this:
> 
> module lib_ns.module_ns;
> extrern(C++, lib_ns) extern(C++, module_ns) void foo();
> 
> The name is:
> lib_ns.module_ns.lib_ns.module_ns.foo(); // <- ....words can't even

I have no idea why it would be necessary to write such. I suspect you are 
unfamiliar with the uses of 'alias' to refer from one scope to names in another.


> Was that a deliberate
> strategy? I feel like that strategy's been used before.

You repeatedly impugn my motives and/or my mental stability. While that doesn't 
bother me, it really does not help your case. Please just stick to the technical 
issue. Believe it or not, I really want to help you (and Laeeth and Atila) be 
successful with this.


More information about the Digitalmars-d mailing list