Thread overview | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
March 08, 2018 D and C++ undefined reference when namespace | ||||
---|---|---|---|---|
| ||||
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 |
March 08, 2018 Re: D and C++ undefined reference when namespace | ||||
---|---|---|---|---|
| ||||
Posted in reply to Markus | 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
|
March 08, 2018 Re: D and C++ undefined reference when namespace | ||||
---|---|---|---|---|
| ||||
Posted in reply to Markus | 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, > Markus https://forum.dlang.org/thread/mailman.2458.1448772039.22025.digitalmars-d@puremagic.com seems to describe my issue. To quote Walter Wright > 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. 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 |
March 08, 2018 Re: D and C++ undefined reference when namespace | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On Thursday, 8 March 2018 at 16:19:40 UTC, Steven Schveighoffer wrote: > 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 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. |
March 08, 2018 Re: D and C++ undefined reference when namespace | ||||
---|---|---|---|---|
| ||||
Posted in reply to Markus | On 3/8/18 11:23 AM, Markus wrote:
> 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,
>> Markus
>
> https://forum.dlang.org/thread/mailman.2458.1448772039.22025.digitalmars-d@puremagic.com
>
> seems to describe my issue.
> To quote Walter Wright
>> 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.
> in my opinion, that's really annoying for C++ wrapper devs.
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.
-Steve
|
March 08, 2018 Re: D and C++ undefined reference when namespace | ||||
---|---|---|---|---|
| ||||
Posted in reply to Markus | 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 |
March 08, 2018 Re: D and C++ undefined reference when namespace | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | 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. > > -Steve 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" :) |
March 08, 2018 Re: D and C++ undefined reference when namespace | ||||
---|---|---|---|---|
| ||||
Posted in reply to Markus | 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
|
March 08, 2018 Re: D and C++ undefined reference when namespace | ||||
---|---|---|---|---|
| ||||
Posted in reply to Markus | 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
|
March 08, 2018 Re: D and C++ undefined reference when namespace | ||||
---|---|---|---|---|
| ||||
Posted in reply to Markus | 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 |
Copyright © 1999-2021 by the D Language Foundation