extern(C++, ns) is wrong

Jonathan M Davis newsgroup.d at jmdavisprog.com
Wed Sep 12 04:39:17 UTC 2018


On Tuesday, September 11, 2018 9:59:30 PM MDT Danni Coy via Digitalmars-d 
wrote:
> So my understanding is that the main issue with extern(C++,"ns") is
> functions that have different C++ name-spaces overriding each other in
> unexpected ways.
> How feasible is to simply disallow functions/variables/objects/... with
> the same name but a different "ns" being in the same module?

If we had extern(C++, "NS"), then all it would affect would be mangling and
all of the normal rules for conflicting symbols would be in force. So, if
you tried to put two symbols with the same name but from different
namespaces in the same module, you'd get an error just like if they were D
functions that conflicted. Disallowing it wouldn't be the problem. The
problem would be if you were trying to match the C++ header file and thus
have the two namespaces in the same file without a conflict, and that
wouldn't work unless you could do something like put the symbol inside a
struct or template to effectively namespace it - or if the current
extern(C++, NS) mechanism were left in place in addition to adding
extern(C++, "NS").

But for the most part, this is a non-issue, because the sane thing to do
would be to just put different namespaces in different modules even if they
were in the same header file in C++ - maybe pkg.headerfile.namespace instead
of pkg.headerfile like you might do if everything in the header file were in
the same namespace. It might be more of a problem with something that
generated the bindings automatically, but mostly, the issue seems to be that
Walter wants to be able to completely follow the C++ header scheme when you
create the bindings, whereas most of the rest of us don't really care about
being that exact about it if the header file did something like have
multiple namespaces with symbols that would conflict if they were in the
same namespace. Since the current scheme effectively creates namespaces
inside of the module instead of just affecting the name mangling, you can
stick as many namespaces in the module as you want without worrying about
conflicts, but you then get other fun problems like having to declare
everything in the namespace sequentially and having to refer everything in
the namespace with the namespace unless you alias it all.

So really, the most flexible solution would probably to have
extern(C++, "NS") which only affects the mangling and then make sure that it
works to do something like

struct Namespace
{
    extern(C++, "Namespace") static void foo(int bar);
}

thereby allowing you to have symbols from multiple namespaces in the same
module even if they have conflicting names. In most cases, people would then
just do

extern(C++, "Namespace") void foo(int bar);

and it's nice and simple, whereas if they really wanted to put conflicting
symbols in the same module instead of just putting them in separate module
like you would with D symbols, they could then explicitly namespace them.
But given what we already have in the language, the simplest alternative
would be to just add

extern(C++, "Namespace")

and leave

extern(C++, Namespace)

so that most code could use extern(C++, "Namespace"), and those rare cases
where you really don't want to put conflicting symbols in separate modules,
you use the current scheme of extern(C++, Namespace). The main downside is
that having both constructs risks being confusing. Really though, there
isn't much of a downside to the extern(C++, "Namespace") solution even if it
were the only one.

- Jonathan M Davis





More information about the Digitalmars-d mailing list