digitalmars.D - D and C++ undefined reference when namespace
- Markus (36/36) Mar 08 2018 Hi
- Steven Schveighoffer (3/15) Mar 08 2018 did you mean ns_a?
- Markus (39/54) Mar 08 2018 yes, that's clearly the issue in my first post. :) I failed when
- Steven Schveighoffer (21/37) Mar 08 2018 This is a linker error. Your D code is compiling just fine (in other
- Markus (13/32) Mar 08 2018 You are right.
- Steven Schveighoffer (6/20) Mar 08 2018 Ah interesting. What it looks like is that the symbol for the namespace
- Steven Schveighoffer (3/5) Mar 08 2018 This is DEFINITELY a bug.
- Steven Schveighoffer (3/9) Mar 08 2018 https://issues.dlang.org/show_bug.cgi?id=18582
- Markus (4/14) Mar 09 2018 thanks for opening an issue.
- kinke (4/6) Mar 08 2018 C++ mangling is part of the DMD front-end shared by all 3
- Markus (9/50) Mar 08 2018 https://forum.dlang.org/thread/mailman.2458.1448772039.22025.digitalmars...
- Steven Schveighoffer (6/59) Mar 08 2018 Hm... that is over 2 years old. I would agree it would seem like a bad
Hi I got the following c++ code [lib.cpp]: namespace ns_a { class class_a { }; void some_function(class_a*) {;} } and the following d code [main.d]: extern (C++, namespace_a) { class class_a {} void some_function(class_a); } void main() { namespace_a.class_a instance_a; namespace_a.some_function(instance_a); } I'm compiling lib.cpp to a shared library by: g++ -shared lib.cpp -o libissue.so and I'm building and linking it with main.d by dmd main.d -L-lissue -L-L. Then I get the error: main.o: In function `_Dmain': main.d:(.text._Dmain[_Dmain]+0xa): undefined reference to `namespace_a::some_function(namespace_a::class_a*)' collect2: error: ld returned 1 exit status Error: linker exited with status 1 When I move the c++ class_a to another namespace (eg. to namespace_b), I'm able to compile and link! readelf -Ws libissue.so | grep some_function gives me _ZN4ns_a13some_functionEPNS_7class_aE so I don't see any issue. Any idea what I'm missing? I guess some linker flag when compiling libissue.so Cheers, Markus
Mar 08 2018
On 3/8/18 10:27 AM, Markus wrote:Hi I got the following c++ code [lib.cpp]: namespace ns_a { class class_a { }; void some_function(class_a*) {;} } and the following d code [main.d]: extern (C++, namespace_a) {did you mean ns_a? -Steve
Mar 08 2018
On Thursday, 8 March 2018 at 16:19:40 UTC, Steven Schveighoffer wrote:On 3/8/18 10:27 AM, Markus wrote:yes, that's clearly the issue in my first post. :) I failed when I made a minimal sample for this forum [lib.cpp]: namespace ns_a { class class_a { }; void some_function(class_a*) {;} } [other.d]: extern (C++, ns_a) { class class_a {} } [main.d]: import other; extern (C++, ns_a) { void some_function(class_a); } void main() { class_a instance_a; ns_a.some_function(instance_a); } compilation: g++ -shared lib.cpp -o libissue.so dmd main.d -L-lissue -L-L. error: main.o: In function `_Dmain': main.d:(.text._Dmain[_Dmain]+0xa): undefined reference to `ns_a::some_function(ns_a::class_a*)' collect2: error: ld returned 1 exit status Error: linker exited with status 1 symbols: nm --demangle libissue.so | some_function 000000000000059a T ns_a::some_function(ns_a::class_a*) It doesn't seem like an error, but it is. I still don't get it, whey I'm not allowed to split the namespace declarations.Hi I got the following c++ code [lib.cpp]: namespace ns_a { class class_a { }; void some_function(class_a*) {;} } and the following d code [main.d]: extern (C++, namespace_a) {did you mean ns_a? -Steve
Mar 08 2018
On 3/8/18 11:35 AM, Markus wrote:error: main.o: In function `_Dmain': main.d:(.text._Dmain[_Dmain]+0xa): undefined reference to `ns_a::some_function(ns_a::class_a*)' collect2: error: ld returned 1 exit status Error: linker exited with status 1 symbols: nm --demangle libissue.so | some_function 000000000000059a T ns_a::some_function(ns_a::class_a*) It doesn't seem like an error, but it is. I still don't get it, whey I'm not allowed to split the namespace declarations.This is a linker error. Your D code is compiling just fine (in other words, the aforementioned issue is not happening to you), it's just not getting the definition from the dynamic library. When I do this locally on my mac, I get a similar error. When I nm the main.o file vs. the lib.o file, I see different mangled names. It appears that the D mangled name is not doing back references. This is probably why the change to another namespace for the function works (there isn't a back reference) In order to demonstrate this better, I did namespace thenamespace instead of ns_a. The symbol I see in the D file: U __ZN12thenamespace13some_functionEPN12thenamespace7class_aE And in the C++ file: T __ZN12thenamespace13some_functionEPNS_7class_aE Note the difference is instead of 12thenamespace, it's S_, which probably is a back reference. Googled... Yep, I'm right: https://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangle.seq-id I'd recommend filing a bug. -Steve
Mar 08 2018
On Thursday, 8 March 2018 at 17:04:02 UTC, Steven Schveighoffer wrote:On 3/8/18 11:35 AM, Markus wrote: When I do this locally on my mac, I get a similar error. When I nm the main.o file vs. the lib.o file, I see different mangled names. It appears that the D mangled name is not doing back references. This is probably why the change to another namespace for the function works (there isn't a back reference) In order to demonstrate this better, I did namespace thenamespace instead of ns_a. The symbol I see in the D file: U __ZN12thenamespace13some_functionEPN12thenamespace7class_aE And in the C++ file: T __ZN12thenamespace13some_functionEPNS_7class_aE Note the difference is instead of 12thenamespace, it's S_, which probably is a back reference. Googled... Yep, I'm right: https://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangle.seq-id I'd recommend filing a bug. -SteveYou are right. $ dmd -c main.d $ nm main.o | grep some U _ZN4ns_a13some_functionEPN4ns_a7class_aE $ nm lib.o | grep some 0000000000000000 T _ZN4ns_a13some_functionEPNS_7class_aE But when i merge the main.d and other.d I get $ nm main.o | grep some U _ZN4ns_a13some_functionEPNS_7class_aE I tested dmd (2.079.0), gdc and ldc2. All got the same result. Which makes me think, that it's not a bug, but a "feature" :)
Mar 08 2018
On 3/8/18 1:56 PM, Markus wrote:You are right. $ dmd -c main.d $ nm main.o | grep some U _ZN4ns_a13some_functionEPN4ns_a7class_aE $ nm lib.o | grep some 0000000000000000 T _ZN4ns_a13some_functionEPNS_7class_aE But when i merge the main.d and other.d I get $ nm main.o | grep some U _ZN4ns_a13some_functionEPNS_7class_aE I tested dmd (2.079.0), gdc and ldc2. All got the same result. Which makes me think, that it's not a bug, but a "feature" :)Ah interesting. What it looks like is that the symbol for the namespace is considered different between the two files in D-land, but they have the same name in C++-land. So it thinks it's not a back reference, but really it should be. -Steve
Mar 08 2018
On 3/8/18 1:56 PM, Markus wrote:I tested dmd (2.079.0), gdc and ldc2. All got the same result. Which makes me think, that it's not a bug, but a "feature" :)This is DEFINITELY a bug. -Steve
Mar 08 2018
On 3/8/18 2:01 PM, Steven Schveighoffer wrote:On 3/8/18 1:56 PM, Markus wrote:https://issues.dlang.org/show_bug.cgi?id=18582 -SteveI tested dmd (2.079.0), gdc and ldc2. All got the same result. Which makes me think, that it's not a bug, but a "feature" :)This is DEFINITELY a bug.
Mar 08 2018
On Thursday, 8 March 2018 at 21:14:36 UTC, Steven Schveighoffer wrote:On 3/8/18 2:01 PM, Steven Schveighoffer wrote:thanks for opening an issue. MarkusOn 3/8/18 1:56 PM, Markus wrote:https://issues.dlang.org/show_bug.cgi?id=18582 -SteveI tested dmd (2.079.0), gdc and ldc2. All got the same result. Which makes me think, that it's not a bug, but a "feature" :)This is DEFINITELY a bug.
Mar 09 2018
On Thursday, 8 March 2018 at 18:56:04 UTC, Markus wrote:I tested dmd (2.079.0), gdc and ldc2. All got the same result. Which makes me think, that it's not a bug, but a "feature" :)C++ mangling is part of the DMD front-end shared by all 3 compilers, so no surprises there: https://github.com/dlang/dmd/blob/master/src/dmd/cppmangle.d
Mar 08 2018
On Thursday, 8 March 2018 at 15:27:31 UTC, Markus wrote:Hi I got the following c++ code [lib.cpp]: namespace ns_a { class class_a { }; void some_function(class_a*) {;} } and the following d code [main.d]: extern (C++, namespace_a) { class class_a {} void some_function(class_a); } void main() { namespace_a.class_a instance_a; namespace_a.some_function(instance_a); } I'm compiling lib.cpp to a shared library by: g++ -shared lib.cpp -o libissue.so and I'm building and linking it with main.d by dmd main.d -L-lissue -L-L. Then I get the error: main.o: In function `_Dmain': main.d:(.text._Dmain[_Dmain]+0xa): undefined reference to `namespace_a::some_function(namespace_a::class_a*)' collect2: error: ld returned 1 exit status Error: linker exited with status 1 When I move the c++ class_a to another namespace (eg. to namespace_b), I'm able to compile and link! readelf -Ws libissue.so | grep some_function gives me _ZN4ns_a13some_functionEPNS_7class_aE so I don't see any issue. Any idea what I'm missing? I guess some linker flag when compiling libissue.so Cheers, Markushttps://forum.dlang.org/thread/mailman.2458.1448772039.22025.digitalmars-d puremagic.com seems to describe my issue. To quote Walter WrightD 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.in my opinion, that's really annoying for C++ wrapper devs. I failed to describe my issue in the first post. there has to be another.d the function and class have to be in seperate d files. Sorry for the spam
Mar 08 2018
On 3/8/18 11:23 AM, Markus wrote:On Thursday, 8 March 2018 at 15:27:31 UTC, Markus wrote:Hm... that is over 2 years old. I would agree it would seem like a bad limitation. And the error message doesn't seem like a linker error, whereas yours does. If it gets to the linker, D hasn't complained about it. -SteveHi I got the following c++ code [lib.cpp]: namespace ns_a { class class_a { }; void some_function(class_a*) {;} } and the following d code [main.d]: extern (C++, namespace_a) { class class_a {} void some_function(class_a); } void main() { namespace_a.class_a instance_a; namespace_a.some_function(instance_a); } I'm compiling lib.cpp to a shared library by: g++ -shared lib.cpp -o libissue.so and I'm building and linking it with main.d by dmd main.d -L-lissue -L-L. Then I get the error: main.o: In function `_Dmain': main.d:(.text._Dmain[_Dmain]+0xa): undefined reference to `namespace_a::some_function(namespace_a::class_a*)' collect2: error: ld returned 1 exit status Error: linker exited with status 1 When I move the c++ class_a to another namespace (eg. to namespace_b), I'm able to compile and link! readelf -Ws libissue.so | grep some_function gives me _ZN4ns_a13some_functionEPNS_7class_aE so I don't see any issue. Any idea what I'm missing? I guess some linker flag when compiling libissue.so Cheers, Markushttps://forum.dlang.org/thread/mailman.2458.1448772039.22025.digital ars-d puremagic.com seems to describe my issue. To quote Walter WrightD 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.in my opinion, that's really annoying for C++ wrapper devs.
Mar 08 2018