digitalmars.D - extern(C++, NS)
- Manu via Digitalmars-d (35/35) Nov 28 2015 I'm having a lot of trouble with C++ namespaces.
- Walter Bright (13/48) Nov 28 2015 D does not support C++ semantics. You cannot split namespaces into multi...
- Manu via Digitalmars-d (28/59) Nov 28 2015 Then the feature fails. You can't put the entire STL in one file.
- Walter Bright (9/23) Nov 29 2015 You can also do this:
- Manu via Digitalmars-d (14/14) Nov 28 2015 Upon further wasting-my-time, I am starting to suspect the forward
- Manu via Digitalmars-d (4/18) Nov 29 2015 Progress... now when I compile, I get a pop-up dialog box that says:
- Manu via Digitalmars-d (14/33) Nov 29 2015 So, I think this compiler crash is when trying to C++ mangle types
- Walter Bright (4/5) Nov 29 2015 I can't do anything with what you describe. Need reproducible test cases...
- Iain Buclaw via Digitalmars-d (20/62) Nov 29 2015 multiple
- Iain Buclaw via Digitalmars-d (4/23) Nov 29 2015 I keep telling them to fix that. My suggestion of replacing them with
- Jacob Carlborg (5/7) Nov 29 2015 "rejected", what!! Any assertion in the compiler is a bug. Or was that
- Iain Buclaw via Digitalmars-d (8/12) Nov 29 2015 not from the compiler?
- Walter Bright (4/21) Nov 29 2015 I commented there:
- Iain Buclaw via Digitalmars-d (8/33) Nov 29 2015 Many have been reported.
- Walter Bright (3/9) Nov 29 2015 Thank you. Reporting bugs is the right solution, not papering over them.
- Iain Buclaw via Digitalmars-d (6/18) Nov 29 2015 Frankly, I thought things were going well and I was pushing it slowly in
- Manu via Digitalmars-d (8/44) Nov 29 2015 digitalmars-d@puremagic.com> wrote:
- Walter Bright (2/3) Nov 29 2015 Thank you.
- Manu via Digitalmars-d (4/21) Nov 29 2015 Well they took a few hours of my life, and increased my anger level a
- Walter Bright (2/4) Nov 29 2015 Per the pull request comments, file bugzilla issues any time such a mess...
- Iain Buclaw via Digitalmars-d (5/11) Nov 29 2015 I skip the middle-man and file github pull requests. It's much nicer to
- Iain Buclaw via Digitalmars-d (9/37) Nov 29 2015 Correct, you will also get the same message with shared or immutable typ...
- Manu via Digitalmars-d (32/102) Nov 29 2015 It's a serious problem. I haven't been able to find any reasonable
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (5/5) Nov 29 2015 On a related note, does D support inline namespaces? Apparently
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (17/22) Nov 30 2015 I wish someone would shed som light on this as inline namespaces
- Walter Bright (12/26) Nov 30 2015 It'd be worthwhile to learn how D's name lookup system works before decl...
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (9/11) Nov 30 2015 Nobody has said anything about lame. The issue is that you don't
- Walter Bright (3/14) Nov 30 2015 Please examine the example I gave again before assuming how D works.
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (15/26) Nov 30 2015 Yes, the problem I see is:
- Walter Bright (4/5) Nov 30 2015 Summary: if the C++ declarations change then the D ones that interface t...
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (6/11) Nov 30 2015 It might be a given, but as pure C++11 libraries become more
- Timon Gehr (17/21) Nov 30 2015 string inlineNamespace(alias ns)(){
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (5/13) Nov 30 2015 The problem is that the inlined namespace can change without
- Daniel N (13/22) Nov 29 2015 I remember when this feature was under discussion, I tried to
- Manu via Digitalmars-d (4/27) Nov 29 2015 Wow... I just didn't quite get there >_<
- Daniel N (11/13) Nov 29 2015 Sorry, my memory was failing me, I dug up the real source now, it
- Timon Gehr (9/30) Nov 29 2015 It is mostly about implementation now (and figuring out a couple of
- Daniel N (3/12) Nov 29 2015 You're right, thanks! Works like a charm. :)
- Jonathan M Davis (25/35) Nov 29 2015 Aliases usually seem to work a lot like copy-pasting. If you do
- Walter Bright (2/5) Nov 29 2015 More accurately, like C/C++ typedef behavior.
- Manu via Digitalmars-d (14/15) Nov 29 2015 So I'm down to some link errors. I don't understand what's emitting
- Joseph Rushton Wakeling (8/9) Nov 29 2015 Note that this is a problem beyond Manu's use-case. Example:
- Jonathan M Davis (11/22) Nov 29 2015 As long as aliases effectively disappear in the compiler once a
- Manu via Digitalmars-d (5/26) Nov 30 2015 This. This is my experience with aliases too. I have found
- Jonathan M Davis (17/22) Nov 29 2015 While I don't disagree with trying to limit how much of C++ gets
- Timon Gehr (18/22) Nov 29 2015 It's about namespace overloading.
- Kagamin (10/16) Nov 30 2015 Didn't you show how two identical names can be distinguished with
- Manu via Digitalmars-d (22/39) Nov 30 2015 Exactly, the D module system would still be in place. Assuming they
- Walter Bright (11/12) Nov 30 2015 Are you still not understanding how name lookup works in D?
- Walter Bright (8/16) Nov 30 2015 No need to imagine:
- Daniel Murphy (2/15) Nov 30 2015 You're not the only one who thought it should be that way.
- Timon Gehr (2/13) Nov 29 2015
- Walter Bright (4/15) Nov 29 2015 file1.NS.X x;
- deadalnix (4/22) Nov 29 2015 Why not produce something similar to an overload set for C++
- Walter Bright (4/27) Nov 29 2015 Because I'd rather have symbol table lookups done in a consistent manner...
- deadalnix (4/12) Nov 30 2015 The proposed behavior is also not new (as per spec, alas it
I'm having a lot of trouble with C++ namespaces. The problem is, the namespace is not just attributed to the symbol in D, but it's emulated as a named scope. The trouble mostly appears in this situation: file1.d extern(C++, NS) struct X; file2.d extern(C++, NS) struct Y; file3.d import file1, file2; X x; // nope Y y; // nope NS.X x; // NS has multiple definitions... NS.Y y; // NS has multiple definitions... And various other configurations similar to this where multiple files declare symbols in the same C++ namespace, and then something tries to import more than one of them. Circular imports of this sort always cause problems. Additionally to that, I don't really want the C++ namespaces to be visible to D; they should be for mangling purposes only. So I try code like this: private extern(C++, NS) struct Thing {} alias Thing = NS.Thing; The idea being that NS will not be available externally, and they should use Thing in module scope instead, but that doesnt work with errors: Error: module blah class blah.NS.Thing is private It seems aliasing a private thing into the public namespace does not make it accessible via that alias? The only way I've managed to make any of those work is with proxy modules, which static import the C++ module, and then `alias Thing = NS.Thing` into the proxy module's scope. This is horrid, and it doubles my module count. I haven't found another pattern that's reliably workable. Ideas?
Nov 28 2015
On 11/28/2015 8:40 PM, Manu via Digitalmars-d wrote:I'm having a lot of trouble with C++ namespaces. The problem is, the namespace is not just attributed to the symbol in D, but it's emulated as a named scope.It is not "emulated" in D, it is an actual named scope in D.The trouble mostly appears in this situation: file1.d extern(C++, NS) struct X; file2.d extern(C++, NS) struct Y; file3.d import file1, file2; X x; // nope Y y; // nope NS.X x; // NS has multiple definitions... NS.Y y; // NS has multiple definitions... And various other configurations similar to this where multiple files declare symbols in the same C++ namespace, and then something tries to import more than one of them. Circular imports of this sort always cause problems.D does not support C++ semantics. You cannot split namespaces into multiple files in D, nor can you add symbols to an existing namespace. For namespace NS, all the declarations in NS have to be in one file and between the { }, just like any other scope in D.Additionally to that, I don't really want the C++ namespaces to be visible to D; they should be for mangling purposes only.We considered making them for mangling only, and rejected it as unworkable, because then two identical names in different namespaces could not be distinguished by the D symbol table system.So I try code like this: private extern(C++, NS) struct Thing {} alias Thing = NS.Thing; The idea being that NS will not be available externally, and they should use Thing in module scope instead, but that doesnt work with errors: Error: module blah class blah.NS.Thing is private It seems aliasing a private thing into the public namespace does not make it accessible via that alias?Aliases do not change access permissions. They are just aliases.The only way I've managed to make any of those work is with proxy modules, which static import the C++ module, and then `alias Thing = NS.Thing` into the proxy module's scope. This is horrid, and it doubles my module count. I haven't found another pattern that's reliably workable. Ideas?Stop trying to bash D into behaving like C++! It'll just make for horrid code (as you discovered) and make you miserable trying. D has an interface to C++; it does not have C++ semantics.
Nov 28 2015
On 29 November 2015 at 14:57, Walter Bright via Digitalmars-d <digitalmars-d puremagic.com> wrote:D does not support C++ semantics. You cannot split namespaces into multiple files in D, nor can you add symbols to an existing namespace. For namespace NS, all the declarations in NS have to be in one file and between the { }, just like any other scope in D.Then the feature fails. You can't put the entire STL in one file. C++ doesn't namespace per file, it generally namespaces per project... so this is the common case; every module define symbols in the same C++ namespace.I understand, and that's fine, but it's not particularly useful unless I can make the namespace invisible and alias the namespaced symbols into D's module (user-accessible) scope. Otherwise importing 2 modules leads to conflicting namespace and symbol resolution is all messed up.Additionally to that, I don't really want the C++ namespaces to be visible to D; they should be for mangling purposes only.We considered making them for mangling only, and rejected it as unworkable, because then two identical names in different namespaces could not be distinguished by the D symbol table system.Maybe a special case for C++ namespaces? Or some other solution that produces the same result. It's a weird sort of permission this one, it's not that the symbols are 'private'; I intend the user to use them, I just want the C++ hierarchy excluded from the symbol table and only accessibly by controlled/explicit alias.So I try code like this: private extern(C++, NS) struct Thing {} alias Thing = NS.Thing; The idea being that NS will not be available externally, and they should use Thing in module scope instead, but that doesnt work with errors: Error: module blah class blah.NS.Thing is private It seems aliasing a private thing into the public namespace does not make it accessible via that alias?Aliases do not change access permissions. They are just aliases.I don't think I'm doing that at all, I'm just trying to make some C++ code linkable to D, and it doesn't work at all. I think you misunderstood my entire post, I don't want C++ semantics at all, I just want to mangle like C++ for linkage, but the implementation doesn't let me do that. If anything, I'm trying to make C++ extern's behave like D semantics, but namespaces aren't a normal part of D, and don't really have idioms for dealing with this. C++ tends to namespace everything with the same namespace, and that means either I implement the entire C++ library in a single module (no way), or I face this mess. The feature just doesn't work beyond a single file linkage experiment, or I completely missed how I'm supposed to use it.The only way I've managed to make any of those work is with proxy modules, which static import the C++ module, and then `alias Thing = NS.Thing` into the proxy module's scope. This is horrid, and it doubles my module count. I haven't found another pattern that's reliably workable. Ideas?Stop trying to bash D into behaving like C++! It'll just make for horrid code (as you discovered) and make you miserable trying. D has an interface to C++; it does not have C++ semantics.
Nov 28 2015
On 11/28/2015 9:17 PM, Manu via Digitalmars-d wrote:On 29 November 2015 at 14:57, Walter Bright via Digitalmars-d <digitalmars-d puremagic.com> wrote:You can also do this: extern (C++, NS) { mixin(import("file1.d")); mixin(import("file2.d")); }D does not support C++ semantics. You cannot split namespaces into multiple files in D, nor can you add symbols to an existing namespace. For namespace NS, all the declarations in NS have to be in one file and between the { }, just like any other scope in D.Then the feature fails. You can't put the entire STL in one file. C++ doesn't namespace per file, it generally namespaces per project... so this is the common case; every module define symbols in the same C++ namespace.Maybe a special case for C++ namespaces?Please, no. Unending confusion and bugs will result.C++ tends to namespace everything with the same namespace, and that means either I implement the entire C++ library in a single moduleYou only need the declarations, not the implementations.
Nov 29 2015
Upon further wasting-my-time, I am starting to suspect the forward referencing issue may be a bigger problem than it appears. I have lots of aliases, and most of them work, but some of them just don't; "Error: identifier 'Kernel' of 'ep.Kernel' is not defined" (not a very helpful message). It is though, it's defined right next to it's companion, which is declared at the same time, in the same place, but I don't get an error for that one. I think the problem here is that the companion symbol isn't involved in a cross-module reference. I try and reduce the problem, but it always disappears. It only appears when the number of modules and interaction between them becomes sufficient. I suspect that whatever it is that causes namespace forward referencing to fail may also be leading to this problem... just a hunch, but it's the best I've got.
Nov 28 2015
On 29 November 2015 at 16:14, Manu <turkeyman gmail.com> wrote:Upon further wasting-my-time, I am starting to suspect the forward referencing issue may be a bigger problem than it appears. I have lots of aliases, and most of them work, but some of them just don't; "Error: identifier 'Kernel' of 'ep.Kernel' is not defined" (not a very helpful message). It is though, it's defined right next to it's companion, which is declared at the same time, in the same place, but I don't get an error for that one. I think the problem here is that the companion symbol isn't involved in a cross-module reference. I try and reduce the problem, but it always disappears. It only appears when the number of modules and interaction between them becomes sufficient. I suspect that whatever it is that causes namespace forward referencing to fail may also be leading to this problem... just a hunch, but it's the best I've got.Progress... now when I compile, I get a pop-up dialog box that says: "object.Error (0): assert(0) or HLT instruction", and then writes "ICE: unsupported type const(char)[]" to the output.
Nov 29 2015
On 29 November 2015 at 19:42, Manu <turkeyman gmail.com> wrote:On 29 November 2015 at 16:14, Manu <turkeyman gmail.com> wrote:So, I think this compiler crash is when trying to C++ mangle types that it doesn't know how to deal with... interestingly, one of those types is typeof(null), which should work, and be mangled as nullptr_t ? Any slice type (ie, char[]) used anywhere within any scope attributed extern(C++) seems to cause DMD to crash. I have these extern(C++) structs and classes, and within them are a bunch of little D inline functions and helpers to make the C++ extern useful to D. This is where '[]' tends to appear, and the consequent compiler crashes. I have tried: extern (D) void helperMethod(char[] s) { ... }, but extern(D) doesn't seem to do anything here, and it still crashes. Options?Upon further wasting-my-time, I am starting to suspect the forward referencing issue may be a bigger problem than it appears. I have lots of aliases, and most of them work, but some of them just don't; "Error: identifier 'Kernel' of 'ep.Kernel' is not defined" (not a very helpful message). It is though, it's defined right next to it's companion, which is declared at the same time, in the same place, but I don't get an error for that one. I think the problem here is that the companion symbol isn't involved in a cross-module reference. I try and reduce the problem, but it always disappears. It only appears when the number of modules and interaction between them becomes sufficient. I suspect that whatever it is that causes namespace forward referencing to fail may also be leading to this problem... just a hunch, but it's the best I've got.Progress... now when I compile, I get a pop-up dialog box that says: "object.Error (0): assert(0) or HLT instruction", and then writes "ICE: unsupported type const(char)[]" to the output.
Nov 29 2015
On 11/29/2015 1:56 AM, Manu via Digitalmars-d wrote:Options?I can't do anything with what you describe. Need reproducible test cases, not handwaving. It should also be in a separate thread rather than mixed up with the other issue.
Nov 29 2015
On 29 Nov 2015 6:17 am, "Manu via Digitalmars-d" < digitalmars-d puremagic.com> wrote:On 29 November 2015 at 14:57, Walter Bright via Digitalmars-d <digitalmars-d puremagic.com> wrote:multipleD does not support C++ semantics. You cannot split namespaces intonamespacefiles in D, nor can you add symbols to an existing namespace. For},NS, all the declarations in NS have to be in one file and between the {This (and response below about mangling) answers a recent question in a PR I made. I had noticed the same when writing a testsuite case, only to discover you can only declare `extern(C++, std)` once. For me, having all related code for a test close together is a nice-to-have though.just like any other scope in D.Then the feature fails. You can't put the entire STL in one file. C++ doesn't namespace per file, it generally namespaces per project... so this is the common case; every module define symbols in the same C++ namespace.unworkable,Additionally to that, I don't really want the C++ namespaces to be visible to D; they should be for mangling purposes only.We considered making them for mangling only, and rejected it asRenamed imports should work here?because then two identical names in different namespaces could not be distinguished by the D symbol table system.I understand, and that's fine, but it's not particularly useful unless I can make the namespace invisible and alias the namespaced symbols into D's module (user-accessible) scope. Otherwise importing 2 modules leads to conflicting namespace and symbol resolution is all messed up.You may have already noticed, but `extern(C++, NS)` behaves more like importing a module, but rather than the module being in a separate file, it's contents are put inplace of the braces. Like importing modules in D, the namespace name itself is not a strong encapsulation (unlike e.g D enums), so whether you use Thing or NS.Thing, both will resolve to the same symbol. The same should also be true when importing a namespace from another module. I think your idea with aliases was just wishful thinking, aliases themselves never worked like that.Maybe a special case for C++ namespaces? Or some other solution that produces the same result. It's a weird sort of permission this one, it's not that the symbols are 'private'; I intend the user to use them, I just want the C++ hierarchy excluded from the symbol table and only accessibly by controlled/explicit alias.So I try code like this: private extern(C++, NS) struct Thing {} alias Thing = NS.Thing; The idea being that NS will not be available externally, and they should use Thing in module scope instead, but that doesnt work with errors: Error: module blah class blah.NS.Thing is private It seems aliasing a private thing into the public namespace does not make it accessible via that alias?Aliases do not change access permissions. They are just aliases.
Nov 29 2015
On 29 Nov 2015 10:42 am, "Manu via Digitalmars-d" < digitalmars-d puremagic.com> wrote:On 29 November 2015 at 16:14, Manu <turkeyman gmail.com> wrote:I keep telling them to fix that. My suggestion of replacing them with meaningful errors was rejected.Upon further wasting-my-time, I am starting to suspect the forward referencing issue may be a bigger problem than it appears. I have lots of aliases, and most of them work, but some of them just don't; "Error: identifier 'Kernel' of 'ep.Kernel' is not defined" (not a very helpful message). It is though, it's defined right next to it's companion, which is declared at the same time, in the same place, but I don't get an error for that one. I think the problem here is that the companion symbol isn't involved in a cross-module reference. I try and reduce the problem, but it always disappears. It only appears when the number of modules and interaction between them becomes sufficient. I suspect that whatever it is that causes namespace forward referencing to fail may also be leading to this problem... just a hunch, but it's the best I've got.Progress... now when I compile, I get a pop-up dialog box that says: "object.Error (0): assert(0) or HLT instruction", and then writes "ICE: unsupported type const(char)[]" to the output.
Nov 29 2015
On 2015-11-29 11:19, Iain Buclaw via Digitalmars-d wrote:I keep telling them to fix that. My suggestion of replacing them with meaningful errors was rejected."rejected", what!! Any assertion in the compiler is a bug. Or was that not from the compiler? -- /Jacob Carlborg
Nov 29 2015
On 29 Nov 2015 11:30 am, "Jacob Carlborg via Digitalmars-d" < digitalmars-d puremagic.com> wrote:On 2015-11-29 11:19, Iain Buclaw via Digitalmars-d wrote:not from the compiler?I keep telling them to fix that. My suggestion of replacing them with meaningful errors was rejected."rejected", what!! Any assertion in the compiler is a bug. Or was thatSomeone put in those ICE's on the promise that at some point it would be detected in semantic pass before the symbol mangling was requested. That promise was never kept. For reference (or if you enjoy time travelling) https://github.com/D-Programming-Language/dmd/pull/4661
Nov 29 2015
On 11/29/2015 2:40 AM, Iain Buclaw via Digitalmars-d wrote:On 29 Nov 2015 11:30 am, "Jacob Carlborg via Digitalmars-d" <digitalmars-d puremagic.com <mailto:digitalmars-d puremagic.com>> wrote: > > On 2015-11-29 11:19, Iain Buclaw via Digitalmars-d wrote: > >> I keep telling them to fix that. My suggestion of replacing them with >> meaningful errors was rejected. > > > "rejected", what!! Any assertion in the compiler is a bug. Or was that not from the compiler? > Someone put in those ICE's on the promise that at some point it would be detected in semantic pass before the symbol mangling was requested. That promise was never kept. For reference (or if you enjoy time travelling) https://github.com/D-Programming-Language/dmd/pull/4661I commented there: "And any test cases that trigger these ICEs should be filed in bugzilla." What are the bugzilla issues?
Nov 29 2015
On 29 November 2015 at 19:51, Walter Bright via Digitalmars-d < digitalmars-d puremagic.com> wrote:On 11/29/2015 2:40 AM, Iain Buclaw via Digitalmars-d wrote:Many have been reported. https://issues.dlang.org/show_bug.cgi?id=14537 https://issues.dlang.org/show_bug.cgi?id=14178 https://issues.dlang.org/show_bug.cgi?id=14020 https://issues.dlang.org/show_bug.cgi?id=13870 https://issues.dlang.org/show_bug.cgi?id=13693On 29 Nov 2015 11:30 am, "Jacob Carlborg via Digitalmars-d" <digitalmars-d puremagic.com <mailto:digitalmars-d puremagic.com>> wrote: > > On 2015-11-29 11:19, Iain Buclaw via Digitalmars-d wrote: > >> I keep telling them to fix that. My suggestion of replacing them with >> meaningful errors was rejected. > > > "rejected", what!! Any assertion in the compiler is a bug. Or was that not from the compiler? > Someone put in those ICE's on the promise that at some point it would be detected in semantic pass before the symbol mangling was requested. That promise was never kept. For reference (or if you enjoy time travelling) https://github.com/D-Programming-Language/dmd/pull/4661I commented there: "And any test cases that trigger these ICEs should be filed in bugzilla." What are the bugzilla issues?
Nov 29 2015
On 11/29/2015 1:53 PM, Iain Buclaw via Digitalmars-d wrote:Many have been reported. https://issues.dlang.org/show_bug.cgi?id=14537 https://issues.dlang.org/show_bug.cgi?id=14178 https://issues.dlang.org/show_bug.cgi?id=14020 https://issues.dlang.org/show_bug.cgi?id=13870 https://issues.dlang.org/show_bug.cgi?id=13693Thank you. Reporting bugs is the right solution, not papering over them. Some of those were misclassified, I fixed them.
Nov 29 2015
On 29 November 2015 at 23:02, Walter Bright via Digitalmars-d < digitalmars-d puremagic.com> wrote:On 11/29/2015 1:53 PM, Iain Buclaw via Digitalmars-d wrote:Frankly, I thought things were going well and I was pushing it slowly in the right direction until someone did a rampage over it. Now I'm back to square one trying to work out what's going on with it, and it's going to need a lot more than papering to recover.Many have been reported. https://issues.dlang.org/show_bug.cgi?id=14537 https://issues.dlang.org/show_bug.cgi?id=14178 https://issues.dlang.org/show_bug.cgi?id=14020 https://issues.dlang.org/show_bug.cgi?id=13870 https://issues.dlang.org/show_bug.cgi?id=13693Thank you. Reporting bugs is the right solution, not papering over them.
Nov 29 2015
On 30 Nov 2015 7:56 am, "Iain Buclaw via Digitalmars-d" < digitalmars-d puremagic.com> wrote:On 29 November 2015 at 19:51, Walter Bright via Digitalmars-d <digitalmars-d puremagic.com> wrote:wrote:On 11/29/2015 2:40 AM, Iain Buclaw via Digitalmars-d wrote:On 29 Nov 2015 11:30 am, "Jacob Carlborg via Digitalmars-d" <digitalmars-d puremagic.com <mailto:digitalmars-d puremagic.com>>with> > On 2015-11-29 11:19, Iain Buclaw via Digitalmars-d wrote: > >> I keep telling them to fix that. My suggestion of replacing themthat not>> meaningful errors was rejected. > > > "rejected", what!! Any assertion in the compiler is a bug. Or wasThatfrom the compiler? > Someone put in those ICE's on the promise that at some point it would be detected in semantic pass before the symbol mangling was requested.I also logged 5 yesterday.Many have been reported. https://issues.dlang.org/show_bug.cgi?id=14537 https://issues.dlang.org/show_bug.cgi?id=14178 https://issues.dlang.org/show_bug.cgi?id=14020 https://issues.dlang.org/show_bug.cgi?id=13870 https://issues.dlang.org/show_bug.cgi?id=13693promise was never kept. For reference (or if you enjoy time travelling) https://github.com/D-Programming-Language/dmd/pull/4661I commented there: "And any test cases that trigger these ICEs should be filed in bugzilla." What are the bugzilla issues?
Nov 29 2015
On 11/29/2015 3:54 PM, Manu via Digitalmars-d wrote:I also logged 5 yesterday.Thank you.
Nov 29 2015
On 29 November 2015 at 20:40, Iain Buclaw via Digitalmars-d <digitalmars-d puremagic.com> wrote:On 29 Nov 2015 11:30 am, "Jacob Carlborg via Digitalmars-d" <digitalmars-d puremagic.com> wrote:Well they took a few hours of my life, and increased my anger level a couple of notches.On 2015-11-29 11:19, Iain Buclaw via Digitalmars-d wrote:Someone put in those ICE's on the promise that at some point it would be detected in semantic pass before the symbol mangling was requested. That promise was never kept. For reference (or if you enjoy time travelling) https://github.com/D-Programming-Language/dmd/pull/4661I keep telling them to fix that. My suggestion of replacing them with meaningful errors was rejected."rejected", what!! Any assertion in the compiler is a bug. Or was that not from the compiler?
Nov 29 2015
On 11/29/2015 2:44 AM, Manu via Digitalmars-d wrote:Well they took a few hours of my life, and increased my anger level a couple of notches.Per the pull request comments, file bugzilla issues any time such a message appears.
Nov 29 2015
On 29 November 2015 at 19:52, Walter Bright via Digitalmars-d < digitalmars-d puremagic.com> wrote:On 11/29/2015 2:44 AM, Manu via Digitalmars-d wrote:I skip the middle-man and file github pull requests. It's much nicer to have an issue fixed than reported. It avoids lengthy mail threads down the line. :-)Well they took a few hours of my life, and increased my anger level a couple of notches.Per the pull request comments, file bugzilla issues any time such a message appears.
Nov 29 2015
On 29 Nov 2015 10:57 am, "Manu via Digitalmars-d" < digitalmars-d puremagic.com> wrote:On 29 November 2015 at 19:42, Manu <turkeyman gmail.com> wrote:Correct, you will also get the same message with shared or immutable types, and static arrays. And I will hazard a guess at delegates and lazy parameters too. There is no technical limitation for this, you *can* pass these data structures to C/C++ (except shared and immutable) so long as the struct layout is matching on the other side. At the same time, it may be for the best if you pass the ptr and length explicitly.On 29 November 2015 at 16:14, Manu <turkeyman gmail.com> wrote:So, I think this compiler crash is when trying to C++ mangle types that it doesn't know how to deal with... interestingly, one of those types is typeof(null), which should work, and be mangled as nullptr_t ? Any slice type (ie, char[]) used anywhere within any scope attributed extern(C++) seems to cause DMD to crash.Upon further wasting-my-time, I am starting to suspect the forward referencing issue may be a bigger problem than it appears. I have lots of aliases, and most of them work, but some of them just don't; "Error: identifier 'Kernel' of 'ep.Kernel' is not defined" (not a very helpful message). It is though, it's defined right next to it's companion, which is declared at the same time, in the same place, but I don't get an error for that one. I think the problem here is that the companion symbol isn't involved in a cross-module reference. I try and reduce the problem, but it always disappears. It only appears when the number of modules and interaction between them becomes sufficient. I suspect that whatever it is that causes namespace forward referencing to fail may also be leading to this problem... just a hunch, but it's the best I've got.Progress... now when I compile, I get a pop-up dialog box that says: "object.Error (0): assert(0) or HLT instruction", and then writes "ICE: unsupported type const(char)[]" to the output.
Nov 29 2015
On 29 November 2015 at 20:17, Iain Buclaw via Digitalmars-d <digitalmars-d puremagic.com> wrote:On 29 Nov 2015 6:17 am, "Manu via Digitalmars-d" <digitalmars-d puremagic.com> wrote:It's a serious problem. I haven't been able to find any reasonable solution. I've tried a bunch of stuff. I think the cleanest solutions would be to either fix this, or to allow public aliasing of private namespaces, that way the namespace is kept in it's box and never pollutes the user's module scope on import.On 29 November 2015 at 14:57, Walter Bright via Digitalmars-d <digitalmars-d puremagic.com> wrote:This (and response below about mangling) answers a recent question in a PR I made. I had noticed the same when writing a testsuite case, only to discover you can only declare `extern(C++, std)` once. For me, having all related code for a test close together is a nice-to-have though.D does not support C++ semantics. You cannot split namespaces into multiple files in D, nor can you add symbols to an existing namespace. For namespace NS, all the declarations in NS have to be in one file and between the { }, just like any other scope in D.Then the feature fails. You can't put the entire STL in one file. C++ doesn't namespace per file, it generally namespaces per project... so this is the common case; every module define symbols in the same C++ namespace.How? I tried this every way I could think; import x.y.NS : Thing; // expects that NS is a file... import x.y : Thing = NS.Thing; // doesn't like 'NS.' in this statement import x.y : this = NS; // ...or something. yeah, I was getting hopeful I could only make this work with a proxy module, which doubles my module count: internal/thing.d: module x.y.internal.thing; extern(C++, NS) struct Thing {} thing.d: module x.y.thing; import x.y.internal.thing; // pollutes the local namespace with NS, but since it's not public it doesn't cascade outwards alias Thing = NS.Thing; // aliases to a public module-level symbol user.d: import x.y.thing; Thing t; // hooray, it works!Renamed imports should work here?I understand, and that's fine, but it's not particularly useful unless I can make the namespace invisible and alias the namespaced symbols into D's module (user-accessible) scope. Otherwise importing 2 modules leads to conflicting namespace and symbol resolution is all messed up.Additionally to that, I don't really want the C++ namespaces to be visible to D; they should be for mangling purposes only.We considered making them for mangling only, and rejected it as unworkable, because then two identical names in different namespaces could not be distinguished by the D symbol table system.Yup, but `import` doesn't seem to have tools to deal with this case.You may have already noticed, but `extern(C++, NS)` behaves more like importing a module, but rather than the module being in a separate file, it's contents are put inplace of the braces.Maybe a special case for C++ namespaces? Or some other solution that produces the same result. It's a weird sort of permission this one, it's not that the symbols are 'private'; I intend the user to use them, I just want the C++ hierarchy excluded from the symbol table and only accessibly by controlled/explicit alias.So I try code like this: private extern(C++, NS) struct Thing {} alias Thing = NS.Thing; The idea being that NS will not be available externally, and they should use Thing in module scope instead, but that doesnt work with errors: Error: module blah class blah.NS.Thing is private It seems aliasing a private thing into the public namespace does not make it accessible via that alias?Aliases do not change access permissions. They are just aliases.Like importing modules in D, the namespace name itself is not a strong encapsulation (unlike e.g D enums), so whether you use Thing or NS.Thing, both will resolve to the same symbol. The same should also be true when importing a namespace from another module.It all goes south when you realise that every file in a C++ project tends to be in the same namespace. Import 2 of them, and then they start hiding eachother, and it all goes south very quickly.I think your idea with aliases was just wishful thinking, aliases themselves never worked like that.I thought aliases did produce a symbol in the scope they are declared? Or do you mean with the private thing? Yeah... Aliases are often used to sort out these sorts of scope/namespacing issues, I've seen it come up lots of times.
Nov 29 2015
On a related note, does D support inline namespaces? Apparently it affects mangling: http://stackoverflow.com/questions/29764869/can-inline-namespaces-be-used-to-keep-backwards-compatibility-in-a-shared-librar I use inline namespaces quite a bit and am curious of how D resolves those.
Nov 29 2015
On Sunday, 29 November 2015 at 11:13:03 UTC, Ola Fosheim Grøstad wrote:On a related note, does D support inline namespaces? Apparently it affects mangling: http://stackoverflow.com/questions/29764869/can-inline-namespaces-be-used-to-keep-backwards-compatibility-in-a-shared-librar I use inline namespaces quite a bit and am curious of how D resolves those.I wish someone would shed som light on this as inline namespaces is what libraries will use in the future in order to do versioning and target different architectures, the one marked "inline" is made active and can be directly accessed through "X::decl" or "X::version1::decl" in c++: namespace X { inline namespace version1 { decl.... } namespace version2 { decl.... } } Seems to me that D needs to embed clang and that the current bindings-only approach will not survive C++11 and later standards.
Nov 30 2015
On 11/30/2015 2:26 AM, Ola Fosheim Grøstad wrote:I wish someone would shed som light on this as inline namespaces is what libraries will use in the future in order to do versioning and target different architectures, the one marked "inline" is made active and can be directly accessed through "X::decl" or "X::version1::decl" in c++: namespace X { inline namespace version1 { decl.... } namespace version2 { decl.... } } Seems to me that D needs to embed clang and that the current bindings-only approach will not survive C++11 and later standards.It'd be worthwhile to learn how D's name lookup system works before declaring it lame and insufficient: extern (C++, X) { extern (C++, version1) { enum e = 3; } } int x = e; int y = X.e; int z = X.version1.e; compiles successfully.
Nov 30 2015
On Monday, 30 November 2015 at 17:38:06 UTC, Walter Bright wrote:It'd be worthwhile to learn how D's name lookup system works before declaring it lame and insufficient:Nobody has said anything about lame. The issue is that you don't need to know of "version1" on the C++ side. One purpose is to use the "inline" as a switch, so that you can use macros to turn on and off different library subsets. "inline" is injected in front of namespaces that are to be accessible in the parent, and that injection can be done by a macro. But on the D side you need to know of "version1" if D does not parse C++ headers. Which is a maintenance burden.
Nov 30 2015
On 11/30/2015 10:51 AM, Ola Fosheim Grøstad wrote:On Monday, 30 November 2015 at 17:38:06 UTC, Walter Bright wrote:Did you look at the example I posted?It'd be worthwhile to learn how D's name lookup system works before declaring it lame and insufficient:Nobody has said anything about lame. The issue is that you don't need to know of "version1" on the C++ side.One purpose is to use the "inline" as a switch, so that you can use macros to turn on and off different library subsets. "inline" is injected in front of namespaces that are to be accessible in the parent, and that injection can be done by a macro. But on the D side you need to know of "version1" if D does not parse C++ headers. Which is a maintenance burden.Please examine the example I gave again before assuming how D works.
Nov 30 2015
On Monday, 30 November 2015 at 19:38:53 UTC, Walter Bright wrote:On 11/30/2015 10:51 AM, Ola Fosheim Grøstad wrote:Yes, the problem I see is: 1. You need to know about "version1" which is an internal namespace on the C++ side, so you cannot just create binding to the documented API, but need to go through the source code just to discover that "version1" exists. 2. If the library internals changes on the C++ side it causes problems for D application code, but not for C++ application code. 3. In order to keep the D and the C++ side call the same set of APIs (if desired) you also need to know on the D side whether the current C++ configuration has enabled "version1" or "version2" (+ a bunch of other potential variations). In essence the C++ model isn't friendly to foreign languages. They keep bolting on "neat hacks" to extend the language in nonbreaking "transparent" ways (on the C++ side).On Monday, 30 November 2015 at 17:38:06 UTC, Walter Bright wrote:Did you look at the example I posted?It'd be worthwhile to learn how D's name lookup system works before declaring it lame and insufficient:Nobody has said anything about lame. The issue is that you don't need to know of "version1" on the C++ side.
Nov 30 2015
On 11/30/2015 12:47 PM, Ola Fosheim Grøstad wrote:[...]Summary: if the C++ declarations change then the D ones that interface to it have to change, too. I'd have to say that's a given.
Nov 30 2015
On Monday, 30 November 2015 at 21:42:19 UTC, Walter Bright wrote:On 11/30/2015 12:47 PM, Ola Fosheim Grøstad wrote:It might be a given, but as pure C++11 libraries become more common people will need a way to deal with inlined namespaces in a way that isn't annoying. And if the changes does not show up in the mangling, then it won't be caught at link-time either. We'll see...[...]Summary: if the C++ declarations change then the D ones that interface to it have to change, too. I'd have to say that's a given.
Nov 30 2015
On 11/29/2015 12:13 PM, Ola Fosheim Grøstad wrote:On a related note, does D support inline namespaces? Apparently it affects mangling: http://stackoverflow.com/questions/29764869/can-inline-namespaces-be-used-to-keep-backwards-compatibility-in-a-shared-librarNamespaces affect mangling. The inline keyword doesn't.I use inline namespaces quite a bit and am curious of how D resolves those.string inlineNamespace(alias ns)(){ string s; foreach(m;__traits(allMembers,ns)) s~=`alias `~m~`=`~__traits(identifier,ns)~`.`~m~`;`; return s; } extern(C++,std){ extern(C++,version1){ void bar(){} } mixin(inlineNamespace!version1); extern(C++,version2){ void bar(){} } }
Nov 30 2015
On Monday, 30 November 2015 at 14:22:17 UTC, Timon Gehr wrote:On 11/29/2015 12:13 PM, Ola Fosheim Grøstad wrote:The problem is that the inlined namespace can change without affecting C++ code. That makes it difficult to make stable bindings for D as it is transparent in C++, but non-transparent in D. Right?On a related note, does D support inline namespaces? Apparently it affects mangling: http://stackoverflow.com/questions/29764869/can-inline-namespaces-be-used-to-keep-backwards-compatibility-in-a-shared-librarNamespaces affect mangling. The inline keyword doesn't.
Nov 30 2015
On Sunday, 29 November 2015 at 10:58:48 UTC, Manu wrote:On 29 November 2015 at 20:17, Iain Buclaw via Digitalmars-dI remember when this feature was under discussion, I tried to argue against extern c++ creating a new scope, but alas no avail. So my current workaround looks something like this(but I didn't use it on a large scale yet): private static struct Hidden { public: extern(C++, std) int fun(); } // autogenerate all aliases with 'static foreach'? alias fun = Hidden.std.fun; if only static foreach would get accepted one day...I think your idea with aliases was just wishful thinking, aliases themselves never worked like that.I thought aliases did produce a symbol in the scope they are declared? Or do you mean with the private thing? Yeah... Aliases are often used to sort out these sorts of scope/namespacing issues, I've seen it come up lots of times.
Nov 29 2015
On 29 November 2015 at 21:22, Daniel N via Digitalmars-d <digitalmars-d puremagic.com> wrote:On Sunday, 29 November 2015 at 10:58:48 UTC, Manu wrote:Wow... I just didn't quite get there >_< That's really horrible! But thanks! ;)On 29 November 2015 at 20:17, Iain Buclaw via Digitalmars-dI remember when this feature was under discussion, I tried to argue against extern c++ creating a new scope, but alas no avail. So my current workaround looks something like this(but I didn't use it on a large scale yet): private static struct Hidden { public: extern(C++, std) int fun(); } // autogenerate all aliases with 'static foreach'? alias fun = Hidden.std.fun; if only static foreach would get accepted one day...I think your idea with aliases was just wishful thinking, aliases themselves never worked like that.I thought aliases did produce a symbol in the scope they are declared? Or do you mean with the private thing? Yeah... Aliases are often used to sort out these sorts of scope/namespacing issues, I've seen it come up lots of times.
Nov 29 2015
On Sunday, 29 November 2015 at 11:29:58 UTC, Manu wrote:Wow... I just didn't quite get there >_< That's really horrible! But thanks! ;)Sorry, my memory was failing me, I dug up the real source now, it was a while ago and I hacked around a lot before I got it working, this is what I ended up with. private extern(C++, std) { public: int fun(); } // autogenerate all aliases with 'static foreach'? alias fun = std.fun;
Nov 29 2015
On 11/29/2015 12:22 PM, Daniel N wrote:On Sunday, 29 November 2015 at 10:58:48 UTC, Manu wrote:It is mostly about implementation now (and figuring out a couple of corner cases, for which the first version could just deny support). Something like this seems to be enough for your needs though: mixin({string s; foreach(m;__traits(allMembers,std)) s~=`alias `~m~`=std.`~m~`;`; return s; }());On 29 November 2015 at 20:17, Iain Buclaw via Digitalmars-dI remember when this feature was under discussion, I tried to argue against extern c++ creating a new scope, but alas no avail. So my current workaround looks something like this(but I didn't use it on a large scale yet): private static struct Hidden { public: extern(C++, std) int fun(); } // autogenerate all aliases with 'static foreach'? alias fun = Hidden.std.fun; if only static foreach would get accepted one day...I think your idea with aliases was just wishful thinking, aliases themselves never worked like that.I thought aliases did produce a symbol in the scope they are declared? Or do you mean with the private thing? Yeah... Aliases are often used to sort out these sorts of scope/namespacing issues, I've seen it come up lots of times.
Nov 29 2015
On Sunday, 29 November 2015 at 13:18:16 UTC, Timon Gehr wrote:It is mostly about implementation now (and figuring out a couple of corner cases, for which the first version could just deny support).Awesome, much looking forwards to it!Something like this seems to be enough for your needs though: mixin({string s; foreach(m;__traits(allMembers,std)) s~=`alias `~m~`=std.`~m~`;`; return s; }());You're right, thanks! Works like a charm. :)
Nov 29 2015
On Sunday, 29 November 2015 at 10:58:48 UTC, Manu wrote:On 29 November 2015 at 20:17, Iain Buclaw via Digitalmars-d <digitalmars-d puremagic.com> wrote:Aliases usually seem to work a lot like copy-pasting. If you do something like alias New = Orig; then everywhere that New is used in the code, it's effectively replaced with Orig, and you never even see it in any error messages. It's pretty much just for the programmer's benefit - e.g. avoiding having to type out the entire import path for a symbol over and over: alias foo = some.pkg.somewhere.foo; But there's still really only one symbol that the compiler is dealing with. It's kind of like how the C/C++ compiler never really sees macros, though it's more controlled than that. For instance, try compiling this code on a 32-bit system: long val; size_t i = val; You'll get an error message complaining about trying to convert a long to a uint, just like if the code looked like long val; uint i = val; The only places that I can think of where aliases don't act quite like this are when they're not used to replace one symbol with another - e.g. with alias this or with using alias to bring a base class overload into the scope of a derived class. - Jonathan M DavisI think your idea with aliases was just wishful thinking, aliases themselves never worked like that.I thought aliases did produce a symbol in the scope they are declared? Or do you mean with the private thing? Yeah... Aliases are often used to sort out these sorts of scope/namespacing issues, I've seen it come up lots of times.
Nov 29 2015
On 11/29/2015 4:36 AM, Jonathan M Davis wrote:But there's still really only one symbol that the compiler is dealing with. It's kind of like how the C/C++ compiler never really sees macros, though it's more controlled than that.More accurately, like C/C++ typedef behavior.
Nov 29 2015
On 29 November 2015 at 19:56, Manu <turkeyman gmail.com> wrote:...So I'm down to some link errors. I don't understand what's emitting these (or not, it seems)... I've messed around a lot. Is __ClassZ the typeinfo? Why would that be missing? Because it's extern(C++)? I tried removing that and it made no difference :/ 2> Error 42: Symbol Undefined _D15TypeInfo_Struct6__vtblZ 2>bin\Debug_x64\dplug.obj(dplug) 2> Error 42: Symbol Undefined _D14TypeInfo_Const6__vtblZ 2>bin\Debug_x64\dplug.obj(dplug) 2> Error 42: Symbol Undefined _D10TypeInfo_k6__initZ 2>bin\Debug_x64\dplug.obj(dplug) 2> Error 42: Symbol Undefined _D12TypeInfo_Aya6__initZ 2>bin\Debug_x64\dplug.obj(dplug) 2> Error 42: Symbol Undefined _D5libep9component9Component7__ClassZ
Nov 29 2015
On Sunday, 29 November 2015 at 04:57:28 UTC, Walter Bright wrote:Aliases do not change access permissions. They are just aliases.Note that this is a problem beyond Manu's use-case. Example: subtyping via alias this currently requires the alias'd entity to be public, contra the example given on TDPL p.231 (see https://issues.dlang.org/show_bug.cgi?id=10996 for details). This means that to use subtyping in practice requires internal implementation details to be revealed to the user, which isn't very nice :-(
Nov 29 2015
On Sunday, 29 November 2015 at 12:39:14 UTC, Joseph Rushton Wakeling wrote:On Sunday, 29 November 2015 at 04:57:28 UTC, Walter Bright wrote:As long as aliases effectively disappear in the compiler once a replacement has been made, and they don't end up in error messages, allowing aliases to muck with anything about the original symbol seems like a recipe for disaster, though I can certainly see why folks would want it (and arguably, it would be a lot more user-friendly if the aliases showed up in the error messages along with the original symbol rather than outright disappearing). - Jonathan M DavisAliases do not change access permissions. They are just aliases.Note that this is a problem beyond Manu's use-case. Example: subtyping via alias this currently requires the alias'd entity to be public, contra the example given on TDPL p.231 (see https://issues.dlang.org/show_bug.cgi?id=10996 for details). This means that to use subtyping in practice requires internal implementation details to be revealed to the user, which isn't very nice :-(
Nov 29 2015
On 29 November 2015 at 22:58, Jonathan M Davis via Digitalmars-d <digitalmars-d puremagic.com> wrote:On Sunday, 29 November 2015 at 12:39:14 UTC, Joseph Rushton Wakeling wrote:This. This is my experience with aliases too. I have found disappearance of aliases has been a source of confusion on numerous occasions.On Sunday, 29 November 2015 at 04:57:28 UTC, Walter Bright wrote:As long as aliases effectively disappear in the compiler once a replacement has been made, and they don't end up in error messages, allowing aliases to muck with anything about the original symbol seems like a recipe for disaster, though I can certainly see why folks would want it (and arguably, it would be a lot more user-friendly if the aliases showed up in the error messages along with the original symbol rather than outright disappearing). - Jonathan M DavisAliases do not change access permissions. They are just aliases.Note that this is a problem beyond Manu's use-case. Example: subtyping via alias this currently requires the alias'd entity to be public, contra the example given on TDPL p.231 (see https://issues.dlang.org/show_bug.cgi?id=10996 for details). This means that to use subtyping in practice requires internal implementation details to be revealed to the user, which isn't very nice :-(
Nov 30 2015
On Sunday, 29 November 2015 at 04:57:28 UTC, Walter Bright wrote:D does not support C++ semantics. You cannot split namespaces into multiple files in D, nor can you add symbols to an existing namespace. For namespace NS, all the declarations in NS have to be in one file and between the { }, just like any other scope in D.While I don't disagree with trying to limit how much of C++ gets dragged into D to support linking with C++ code, I don't see how this approach with namespaces is tenable in anything much more complicated than a toy example. C++ namespaces aren't used at all like D modules. Entire libraries are put into a single namespace. For instance, are you suggesting that we put all of the bindings for C++'s standard library in a single file? Large libraries such as Boost or Qt do often split up their namespaces into sub-namespaces, but they're still usually far larger than anyone would want to stick in a single file. It seems to me that the only way that the current behavior stands any chance of being tenable is if almost no one is using C++ bindings, and when they do, they keep them to an absolute bare minimum. It certainly doesn't fly well with binding something like the STL or Qt. - Jonathan M Davis
Nov 29 2015
On 11/29/2015 05:57 AM, Walter Bright wrote:D does not support C++ semantics. You cannot split namespaces into multiple files in D, nor can you add symbols to an existing namespace. For namespace NS, all the declarations in NS have to be in one file and between the { }, just like any other scope in D.It's about namespace overloading. The following works, even though no scopes are actually extended with new symbols. module other; template foo(){ // a scope void foo(){} } // ---- import other; alias foo=other.foo; template foo(){ // another scope void foo(int){} } void main(){ foo(); // successful foo(2); // ditto }
Nov 29 2015
On Sunday, 29 November 2015 at 04:57:28 UTC, Walter Bright wrote:We considered making them for mangling only, and rejected it as unworkable, because then two identical names in different namespaces could not be distinguished by the D symbol table system.Didn't you show how two identical names can be distinguished with D symbol table system: On Sunday, 29 November 2015 at 18:29:14 UTC, Walter Bright wrote:file1.NS.X x; file2.NS.Y y;It also works the same for C bindings: they share (empty) namespace, but identical C declarations can be distinguished in D if they are in different modules. Maybe it's better to ignore C namespaces and rely on D module system instead? Though I don't know why one would want to disallow access to a C++ namespace.
Nov 30 2015
On 30 November 2015 at 20:12, Kagamin via Digitalmars-d <digitalmars-d puremagic.com> wrote:On Sunday, 29 November 2015 at 04:57:28 UTC, Walter Bright wrote:Exactly, the D module system would still be in place. Assuming they were in defferent modules, then the D module system would keep them out of conflict naturally, with rules identical to the normal D rules. I imagined this; C++ namespace is for mangling, D module is for scoping. That's not how it seems to be, so my intuition was dead wrong, but my weekend's experience has convinced me it would be better how I initially intuited. Thing is, we're presenting a C++ API to D, so we want to present it in D's terms, that is, the API is distributed among D modules in a way that makes sense to a D user. I don't want to present the API in C++ terms, and it's not even practical; stuffing the entire C++ API into a single D module is crazy. In the cases I'm interested in, the C++ API is possibly larger than the entire D codebase that's attached to it. Walter said this: "Stop trying to bash D into behaving like C++! [...]", which I was kind of offended by, because it couldn't have been further from my intent. I'm trying to bash C++ into behaving like D, and the best way to do that would be to say that C++ namespace is for mangling only, and expect that the dev will distribute the C++ symbols among D modules in such a way that makes sense to D developers consuming the API.We considered making them for mangling only, and rejected it as unworkable, because then two identical names in different namespaces could not be distinguished by the D symbol table system.Didn't you show how two identical names can be distinguished with D symbol table system: On Sunday, 29 November 2015 at 18:29:14 UTC, Walter Bright wrote:file1.NS.X x; file2.NS.Y y;It also works the same for C bindings: they share (empty) namespace, but identical C declarations can be distinguished in D if they are in different modules. Maybe it's better to ignore C namespaces and rely on D module system instead? Though I don't know why one would want to disallow access to a C++ namespace.
Nov 30 2015
On 11/30/2015 3:42 AM, Manu via Digitalmars-d wrote:That's not how it seems to be,Are you still not understanding how name lookup works in D? (You won't be the first. I explain it to people over and over, and nobody gets it. I have no idea why it is so hard to understand.) C++ namespaces introduce scopes. The normal D lookup rules for scoped names applies. When names in C++ namespaces are mangled, they are mangled like C++ names would be, not like D names would be. Lookup rules, apply one by one until found: 1. Look up in current scope. 2. Look up in imported scopes. Error if more than one is found. 3. Go up a level, and goto 1.
Nov 30 2015
On 11/30/2015 3:42 AM, Manu via Digitalmars-d wrote:Exactly, the D module system would still be in place. Assuming they were in defferent modules, then the D module system would keep them out of conflict naturally, with rules identical to the normal D rules. I imagined this;No need to imagine: "Namespaces create a new named scope that is imported into its enclosing scope." -- http://dlang.org/spec/attribute.html#namespaceC++ namespace is for mangling, D module is for scoping. That's not how it seems to be, so my intuition was dead wrong, but my weekend's experience has convinced me it would be better how I initially intuited.What about: file1.NS.X x; file2.NS.Y y; ?
Nov 30 2015
On 30/11/2015 10:42 PM, Manu via Digitalmars-d wrote:Exactly, the D module system would still be in place. Assuming they were in defferent modules, then the D module system would keep them out of conflict naturally, with rules identical to the normal D rules. I imagined this; C++ namespace is for mangling, D module is for scoping. That's not how it seems to be, so my intuition was dead wrong, but my weekend's experience has convinced me it would be better how I initially intuited. Thing is, we're presenting a C++ API to D, so we want to present it in D's terms, that is, the API is distributed among D modules in a way that makes sense to a D user. I don't want to present the API in C++ terms, and it's not even practical; stuffing the entire C++ API into a single D module is crazy. In the cases I'm interested in, the C++ API is possibly larger than the entire D codebase that's attached to it.You're not the only one who thought it should be that way.
Nov 30 2015
On 11/29/2015 05:40 AM, Manu via Digitalmars-d wrote:The trouble mostly appears in this situation: file1.d extern(C++, NS) struct X; file2.d extern(C++, NS) struct Y; file3.d import file1, file2; X x; // nope Y y; // nopeThose two actually work for me.NS.X x; // NS has multiple definitions... NS.Y y; // NS has multiple definitions...
Nov 29 2015
On 11/28/2015 8:40 PM, Manu via Digitalmars-d wrote:The trouble mostly appears in this situation: file1.d extern(C++, NS) struct X; file2.d extern(C++, NS) struct Y; file3.d import file1, file2; X x; // nope Y y; // nope NS.X x; // NS has multiple definitions... NS.Y y; // NS has multiple definitions...file1.NS.X x; file2.NS.Y y; works.
Nov 29 2015
On Sunday, 29 November 2015 at 18:29:14 UTC, Walter Bright wrote:On 11/28/2015 8:40 PM, Manu via Digitalmars-d wrote:Why not produce something similar to an overload set for C++ namespace ? An error needs to be issued only if X or Y is duplicated, otherwise, this is fine.The trouble mostly appears in this situation: file1.d extern(C++, NS) struct X; file2.d extern(C++, NS) struct Y; file3.d import file1, file2; X x; // nope Y y; // nope NS.X x; // NS has multiple definitions... NS.Y y; // NS has multiple definitions...file1.NS.X x; file2.NS.Y y; works.
Nov 29 2015
On 11/29/2015 8:31 PM, deadalnix wrote:On Sunday, 29 November 2015 at 18:29:14 UTC, Walter Bright wrote:Because I'd rather have symbol table lookups done in a consistent manner, rather than special casing it everywhere. The above behavior is completely consistent with how everything else works, because it uses the exact same code.On 11/28/2015 8:40 PM, Manu via Digitalmars-d wrote:Why not produce something similar to an overload set for C++ namespace ? An error needs to be issued only if X or Y is duplicated, otherwise, this is fine.The trouble mostly appears in this situation: file1.d extern(C++, NS) struct X; file2.d extern(C++, NS) struct Y; file3.d import file1, file2; X x; // nope Y y; // nope NS.X x; // NS has multiple definitions... NS.Y y; // NS has multiple definitions...file1.NS.X x; file2.NS.Y y; works.
Nov 29 2015
On Monday, 30 November 2015 at 07:45:54 UTC, Walter Bright wrote:The proposed behavior is also not new (as per spec, alas it doesn't work in DMD), as it is the same as for multiple alias this.Why not produce something similar to an overload set for C++ namespace ? An error needs to be issued only if X or Y is duplicated, otherwise, this is fine.Because I'd rather have symbol table lookups done in a consistent manner, rather than special casing it everywhere. The above behavior is completely consistent with how everything else works, because it uses the exact same code.
Nov 30 2015