Thread overview | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
July 27, 2018 Is there any good reason why C++ namespaces are "closed" in D? | ||||
---|---|---|---|---|
| ||||
I understand that being able to "reopen" namespaces in C++ is contentious - anybody can add to the `std` namespace in their own code. D doesn't have anything like it, and instead has packages and modules. So far, so good. But why does this not compile? extern(C++, ns) { void foo(); } extern(C++, ns) { void bar(); } I could maybe understand the limitation if those functions had bodies since we'd be importing the namespace functionality from C++ in a sense (and even then I'm not sure it's a big enough deal). But all I'm trying to do here is tell the D compiler how to mangle symbols. Why would this matter? Imagine a project that parses C++ headers and translates them to D declarations. Imagine that project is trying to parse `#include <vector>`. There will be many, many instances of `namespace std` in there, but such a not-so-hypothetical program can't just go through them and open and close `extern(C++, std)` as it goes along. Such a program can easily do that to `extern(C)`, but doing that to `extern(C++)` is for some reason not allowed. (is there even any semantic difference? extern(C) for a 2nd time is just reopening the global namespace!) One could simply manually `pragma(mangle)` everything up the wazoo, but unfortunately that doesn't work for templates, which, as it turns out, is pretty much everything inside the `std` namespace. My only solution is to keep track of all namespaces at all times and then sort the declarations by namespace, which: 1) Is incredibly tedious 2) Might cause problems with the order of declarations, especially if macros are involved. I can only assume nobody has tried calling a large C++ library from D (Qt doesn't count, no namespaces). Imagine manually organising namespaces in one huge bindings file instead of being able to copy the file layout of the C++ headers! Sigh. Atila |
July 27, 2018 Re: Is there any good reason why C++ namespaces are "closed" in D? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Atila Neves | This limitation really seems to make no sense, especially since you can split up a C++ namespace across multiple D modules, just not inside a single module. |
July 27, 2018 Re: Is there any good reason why C++ namespaces are "closed" in D? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Atila Neves | On 27.07.2018 19:28, Atila Neves wrote:
> I understand that being able to "reopen" namespaces in C++ is contentious - anybody can add to the `std` namespace in their own code. D doesn't have anything like it, and instead has packages and modules. So far, so good.
>
> But why does this not compile?
>
> extern(C++, ns) { void foo(); }
> extern(C++, ns) { void bar(); }
Both of the extern(C++, ns) declarations create a separate namespace declaration. (Which is needed to allow ns.foo and ns.bar respectively.)
I.e. the reason is that it was easier to implement in the compiler. There might be a way to add support for it by overriding overloadInsert in Nspace.
|
July 27, 2018 Re: Is there any good reason why C++ namespaces are "closed" in D? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Atila Neves | On 7/27/2018 10:28 AM, Atila Neves wrote:
> But all I'm trying to do here is tell the D compiler how to mangle symbols.
Namespaces have semantic implications, too, such as overload resolutions. A namespace introduces a new scope, not just a mangling.
> But why does this not compile?
> extern(C++, ns) { void foo(); }
> extern(C++, ns) { void bar(); }
For the same reason that:
struct ns { void foo(); }
struct ns { void bar(); }
doesn't. Being able to crack open a scope and stuff more symbols into it at any point in a program is just madness :-)
However, one can do:
------ module A ---------
extern(C++, ns) { void foo(); }
------ module B ---------
extern(C++, ns) { void bar(); }
------ module C ---------
import A,B;
ns.foo(); // error, A.ns or B.ns?
A.ns.foo(); // ok
Because the compiler sees A.ns as utterly distinct from B.ns, although the mangling will be the same - any conflicts will be the linker's problem.
This is how, for example, extern(C) declarations can exist in many files.
> Such a program can easily do that to `extern(C)`, but doing that to `extern(C++)` is for some reason not allowed.
It is allowed. Just not reopening the same namespace.
Namespaces are a botch in C++, and it is understandable that C++ code bases naturally have grown willy-nilly to utterly ignore any encapsulation principles. It's analogous to how monkey-patching in Ruby was seen initially as a cool feature, but eventually people learned the hard way what a disastrous idea it was.
|
July 27, 2018 Re: Is there any good reason why C++ namespaces are "closed" in D? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | On Friday, 27 July 2018 at 22:50:20 UTC, Walter Bright wrote: > On 7/27/2018 10:28 AM, Atila Neves wrote: >> But all I'm trying to do here is tell the D compiler how to mangle symbols. > > Namespaces have semantic implications, too, such as overload resolutions. A namespace introduces a new scope, not just a mangling. > > > But why does this not compile? > > extern(C++, ns) { void foo(); } > > extern(C++, ns) { void bar(); } > > For the same reason that: > > struct ns { void foo(); } > struct ns { void bar(); } > > doesn't. Being able to crack open a scope and stuff more symbols into it at any point in a program is just madness :-) > > However, one can do: > > ------ module A --------- > extern(C++, ns) { void foo(); } > > ------ module B --------- > extern(C++, ns) { void bar(); } > > ------ module C --------- > import A,B; > ns.foo(); // error, A.ns or B.ns? > A.ns.foo(); // ok > > Because the compiler sees A.ns as utterly distinct from B.ns, although the mangling will be the same - any conflicts will be the linker's problem. > > This is how, for example, extern(C) declarations can exist in many files. > > > Such a program can easily do that to `extern(C)`, but doing > that to `extern(C++)` is for some reason not allowed. > > It is allowed. Just not reopening the same namespace. > > Namespaces are a botch in C++, and it is understandable that C++ code bases naturally have grown willy-nilly to utterly ignore any encapsulation principles. It's analogous to how monkey-patching in Ruby was seen initially as a cool feature, but eventually people learned the hard way what a disastrous idea it was. Thanks for the explanation, Walter. Can you think of a pragmatic solution to Atila's problem? Because it's getting in the way of a decent prize - to be able just to #include CPP headers and link with C++. Obviously some work elsewhere still to do, but translation of headers is worth quite a lot if you are a commercial user and don't have much time to write a first exploratory version. Already just having #include work for a lot of C libraries makes an immense difference. D "doesn't have libraries". Well there's some good stuff on code.dlang.org plus every C library - a few of those, so I hear. And with C++ on top it starts to become about as persuasive as "there are no good jobs in D". (Reminder - we are hiring and we pay well). |
July 27, 2018 Re: Is there any good reason why C++ namespaces are "closed" in D? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Laeeth Isharc | On 7/27/2018 4:15 PM, Laeeth Isharc wrote:
> Can you think of a pragmatic solution to Atila's problem?
One way is for the C++ => D translator to gather all the members of a namespace before trying to emit them. Since D does not impose an order on declarations (unlike C++) it is not constrained to follow the same order.
|
July 28, 2018 Re: Is there any good reason why C++ namespaces are "closed" in D? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Atila Neves Attachments:
| On Fri., 27 Jul. 2018, 10:30 am Atila Neves via Digitalmars-d, < digitalmars-d@puremagic.com> wrote: > I understand that being able to "reopen" namespaces in C++ is contentious - anybody can add to the `std` namespace in their own code. D doesn't have anything like it, and instead has packages and modules. So far, so good. > > But why does this not compile? > > extern(C++, ns) { void foo(); } > extern(C++, ns) { void bar(); } > > I could maybe understand the limitation if those functions had bodies since we'd be importing the namespace functionality from C++ in a sense (and even then I'm not sure it's a big enough deal). But all I'm trying to do here is tell the D compiler how to mangle symbols. > > Why would this matter? Imagine a project that parses C++ headers and translates them to D declarations. Imagine that project is trying to parse `#include <vector>`. There will be many, many instances of `namespace std` in there, but such a not-so-hypothetical program can't just go through them and open and close `extern(C++, std)` as it goes along. Such a program can easily do that to `extern(C)`, but doing that to `extern(C++)` is for some reason not allowed. > > (is there even any semantic difference? extern(C) for a 2nd time > is just reopening the global namespace!) > > One could simply manually `pragma(mangle)` everything up the wazoo, but unfortunately that doesn't work for templates, which, as it turns out, is pretty much everything inside the `std` namespace. > > My only solution is to keep track of all namespaces at all times and then sort the declarations by namespace, which: > > 1) Is incredibly tedious > 2) Might cause problems with the order of declarations, > especially if macros are involved. > > I can only assume nobody has tried calling a large C++ library from D (Qt doesn't count, no namespaces). Imagine manually organising namespaces in one huge bindings file instead of being able to copy the file layout of the C++ headers! > > Sigh. > > Atila > +1 You know how many times I've been upset about this, including the same day that the C++ namespace feature was merged without consulting anyone in the community that intended to use it. Make a PR that implements namespace as a string... I will use that fork of D forever. > |
July 28, 2018 Re: Is there any good reason why C++ namespaces are "closed" in D? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright Attachments:
| On Fri., 27 Jul. 2018, 3:55 pm Walter Bright via Digitalmars-d, < digitalmars-d@puremagic.com> wrote:
> Namespaces are a botch in C++, and it is understandable that C++ code
> bases
> naturally have grown willy-nilly to utterly ignore any encapsulation
> principles.
Correct. And D has modules. Solved.
Literally nobody has ever wanted to use a C++ namespaces as a means of encapsulation in D. We *just* want to mangle our symbol name. We want to keep our code organised consistently with all other D code.
Please, please, please... Please, please please please please please PLEASE support extern(C++, "string_ns") as a mangle-only variant.
Current behaviour can coexist, but let us have a way to express a mangling request without changing the organisation of our D code.
I suggest accepting string, since that will allow us to also access C++ namespaces that conflict with D keywords.
|
July 28, 2018 Re: Is there any good reason why C++ namespaces are "closed" in D? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Manu | On 7/28/2018 11:18 AM, Manu wrote:
> Make a PR that implements namespace as a string... I will use that fork of D forever.
1. Look how it is mangled on the C++ side. (Use "grep" on the object file.)
2. Use:
pragma(mangle, "the mangled name")
|
July 28, 2018 Re: Is there any good reason why C++ namespaces are "closed" in D? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright Attachments:
| On Sat., 28 Jul. 2018, 8:25 pm Walter Bright via Digitalmars-d, < digitalmars-d@puremagic.com> wrote: > On 7/28/2018 11:18 AM, Manu wrote: > > Make a PR that implements namespace as a string... I will use that fork > of D > > forever. > > 1. Look how it is mangled on the C++ side. (Use "grep" on the object file.) > > 2. Use: > > pragma(mangle, "the mangled name") Don't troll me on this one, this is a very sensitive topic! I could have a legit mental breakdown ;) > |
Copyright © 1999-2021 by the D Language Foundation