extern(C++, ns)

Manu via Digitalmars-d digitalmars-d at puremagic.com
Wed Jan 20 15:26:29 PST 2016

On 21 January 2016 at 06:56, Walter Bright via Digitalmars-d
<digitalmars-d at puremagic.com> wrote:
> On 1/20/2016 4:17 AM, Manu via Digitalmars-d wrote:
>> -- name.x.d--------------------
>> module name.x;
>> -- name.y.d--------------------
>> module name.y;
>> import name.x;
>> extern(C++, name) int x;
>> ------------------------------------
> This won't work any more than:
>   import name.y;
>   struct name { }
> would. You can't have two different definitions for the same identifier in
> the same scope, and that's true for any programming language I've heard of.

Of course. But I don't know how you keep missing my point; I didn't
declare something called 'name', I declared something called 'x'.
I don't want this namespace called 'name'; I didn't declare it, and it
causes problems, like this.
The obvious response is "well don't declare it then", but that's not
an option we're allowed. I want to opt-out of the namespace. I'd
prefer the default was to opt-in though.

>> ------------------------------------
>> extern(C++, delegate) int x;
>> ------------------------------------
> Yes, we've talked about that. I'm thinking of a solution where it could be
> written like:
>     extern(C++, delegate_) int x;
> and the C++ name mangler strips off any trailing _.

It's a solution I guess... I wouldn't call it intuitive. Why would
someone reading the code expect that behaviour?
But again, it's completely unnecessary. I don't want a namespace
called 'delegate'.
I don't want to declare any D identifier anywhere called 'delegate', I
just want it to mangle 'x' properly.

You're proposing a work-around to a problem that shouldn't exist in
the first place. The proper solution is to make the problem not exist.

> Note that this problem is NOT resolved by your proposed solution, as this
> wouldn't work, either:
>    extern(C++) int* delegate();

>> You claim this is a problem that must desperately be solved:
>> ------------------------------------
>> int x;
>> extern(C++, ns) int x;
>> ------------------------------------
>> The solution arrives at basically the same problem:
>> ------------------------------------
>> int ns;
>> extern(C++, ns) int x;
>> ------------------------------------
>> We've just robbed peter to pay paul?
> C++ doesn't allow:
>     int ns;
>     namespace ns { ... }
> either, so there can never be a need to solve that problem.

I'm declaring 'x', not 'ns'. using the namespace to resolve conflict
in the first case just creates a second potential for conflict. It's
kicked the can, and hasn't reliably solved the problem. Name conflict
resolution and name mangling are separate issues, it's no good to
conflate them.
I'd rather resolve the conflict in a normal D way like any normal D
user would. I can best choose how to resolve the conflict with
consideration for the case, and this issue has nothing to do with name

>> scanning reflection
>> needs to be retrofit with new tricks to recurse into namespaces:
>> ------------------------------------
>> extern(C++, ns) void f();
>> pragma(msg, __traits(allMembers, mixin(__MODULE__)));
>> ------------------------------------
>>> tuple("object", "ns")
>> ... f() is not present.
>> By extension of this, extern(C++, ns) declarations are incompatible
>> with every single implementation of scanning reflection I've written
>> in the past 6 years, and everyone else's too.
>> All such code needs to be retrofit with new tricks to recurse into ns.
> Seems to me that all that is necessary is to replace:
>   __traits(allMembers, mixin(__MODULE__))
> with:
>    getAllMembersIncludingNs(mixin(__MODULE__))
> and then write getAllMembersIncludingNS() as a function that recursively
> adds members of namespaces. After all, the ugly __traits() was always meant
> to be a building block to be encapsulated by a function that does what is
> really wanted. I wouldn't call it tricky.

">> All such code needs to be retrofit with new tricks to recurse into ns."

I understand I can correct the situation by changing the code, but
there is an awful lot of reflection code that already exists, mostly
in libraries.
Normal programmers don't tend to change library code, they just assume
that it doesn't work.

You guys hate breaking code, I'm surprised you're not more upset by this.
I'm frustrated by the other cases, because you're making me to do work
and waste time here complaining about a problem that simply shouldn't
exist in the first place. This is the one that really upsets me
I don't want the namespace to exist. I just want extern(C++, "ns") to
take a string, not make a scope, every single problem is solved, and
you'll not hear from me for another 6 months.

More information about the Digitalmars-d mailing list