Jump to page: 1 215  
Page
Thread overview
Is there any good reason why C++ namespaces are "closed" in D?
Jul 27, 2018
Atila Neves
Jul 27, 2018
kinke
Jul 27, 2018
Timon Gehr
Jul 27, 2018
Walter Bright
Jul 27, 2018
Laeeth Isharc
Jul 28, 2018
Walter Bright
Jul 30, 2018
Atila Neves
Jul 30, 2018
Walter Bright
Jul 31, 2018
Laeeth Isharc
Aug 01, 2018
Walter Bright
Aug 01, 2018
Manu
Aug 03, 2018
Ali
Jul 28, 2018
Manu
Jul 30, 2018
Atila Neves
Jul 30, 2018
Walter Bright
Jul 31, 2018
Atila Neves
Aug 01, 2018
Walter Bright
Jul 28, 2018
Manu
Jul 29, 2018
Walter Bright
Jul 29, 2018
Manu
Jul 29, 2018
Walter Bright
Jul 29, 2018
Walter Bright
Jul 30, 2018
Atila Neves
Jul 30, 2018
Walter Bright
Jul 30, 2018
Walter Bright
Jul 29, 2018
Nicholas Wilson
Jul 29, 2018
Walter Bright
Jul 29, 2018
Manu
Jul 29, 2018
Walter Bright
Jul 29, 2018
Jonathan M Davis
Jul 29, 2018
kinke
Jul 29, 2018
Jonathan M Davis
Jul 29, 2018
Manu
Jul 30, 2018
Walter Bright
Jul 30, 2018
Nicholas Wilson
Jul 30, 2018
Walter Bright
Jul 30, 2018
Manu
Jul 30, 2018
Walter Bright
Jul 30, 2018
Walter Bright
Jul 29, 2018
ezneh
Jul 29, 2018
Manu
Jul 30, 2018
Walter Bright
Jul 30, 2018
Nicholas Wilson
Jul 30, 2018
Nicholas Wilson
Jul 30, 2018
Manu
Jul 30, 2018
Walter Bright
Jul 30, 2018
Daniel N
Jul 30, 2018
CommanderZot
Jul 30, 2018
Walter Bright
Jul 30, 2018
Manu
Jul 30, 2018
Walter Bright
Jul 30, 2018
Manu
Jul 31, 2018
Walter Bright
Jul 31, 2018
Walter Bright
Jul 31, 2018
Manu
Jul 31, 2018
Jacob Carlborg
Jul 31, 2018
Manu
Jul 31, 2018
Rubn
Aug 01, 2018
Nicholas Wilson
Aug 01, 2018
Walter Bright
Aug 01, 2018
Jonathan M Davis
Aug 01, 2018
Walter Bright
Aug 02, 2018
Rubn
Aug 02, 2018
Walter Bright
Aug 02, 2018
bachmeier
Aug 02, 2018
Rubn
Aug 02, 2018
Johannes Pfau
Aug 02, 2018
Johannes Pfau
Aug 02, 2018
rjframe
Aug 04, 2018
Manu
Aug 05, 2018
Walter Bright
Aug 06, 2018
Manu
Aug 06, 2018
12345swordy
Aug 07, 2018
Walter Bright
Aug 06, 2018
Danni Coy
Aug 06, 2018
bachmeier
Aug 06, 2018
tide
Aug 06, 2018
Walter Bright
Aug 06, 2018
tide
Aug 07, 2018
Walter Bright
Aug 01, 2018
Manu
Aug 01, 2018
Manu
Aug 02, 2018
Walter Bright
Aug 02, 2018
Manu
Aug 02, 2018
Walter Bright
Aug 02, 2018
rikki cattermole
Aug 02, 2018
Walter Bright
Aug 03, 2018
rikki cattermole
Aug 06, 2018
Walter Bright
Aug 02, 2018
Walter Bright
Aug 02, 2018
Manu
Aug 02, 2018
Walter Bright
Aug 02, 2018
Johannes Pfau
Jul 31, 2018
Mathias Lang
Jul 31, 2018
Atila Neves
Aug 01, 2018
Walter Bright
Aug 02, 2018
Johannes Pfau
Aug 02, 2018
Walter Bright
Aug 02, 2018
Daniel N
Aug 02, 2018
rikki cattermole
Aug 02, 2018
Daniel N
Aug 03, 2018
Walter Bright
Aug 03, 2018
Rubn
Aug 04, 2018
Laeeth Isharc
Aug 04, 2018
Manu
Aug 04, 2018
Laeeth Isharc
Aug 06, 2018
Atila Neves
Aug 04, 2018
tide
Aug 04, 2018
Jonathan M Davis
Aug 04, 2018
tid3
Aug 06, 2018
Atila Neves
Aug 04, 2018
tide
Aug 06, 2018
aliak
Aug 03, 2018
Atila Neves
Aug 03, 2018
Daniel N
Aug 03, 2018
CommanderZot
Aug 03, 2018
Walter Bright
Aug 06, 2018
Atila Neves
Aug 07, 2018
Walter Bright
Aug 07, 2018
Nicholas Wilson
Aug 07, 2018
Walter Bright
Aug 07, 2018
Nicholas Wilson
Aug 07, 2018
Walter Bright
Aug 07, 2018
Walter Bright
Aug 07, 2018
Daniel N
Aug 07, 2018
Atila Neves
Aug 07, 2018
Walter Bright
Jul 29, 2018
Manu
Jul 29, 2018
bachmeier
Jul 29, 2018
Seb
Jul 30, 2018
Walter Bright
Jul 30, 2018
Timon Gehr
Jul 29, 2018
Jim Balter
Jul 30, 2018
Atila Neves
Jul 30, 2018
Walter Bright
Jul 31, 2018
Daniel N
Jul 31, 2018
Mathias Lang
Jul 31, 2018
Atila Neves
July 27, 2018
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
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
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
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
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
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
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
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
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
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 ;)

>


« First   ‹ Prev
1 2 3 4 5 6 7 8 9 10 11