Undefined reference to std::nothrow in libsupc++.a of newlib

916 views Asked by At

Now I am trying to cross compile Nuttx with libc++ using arm-none-eabi toolchain. Most of things is fine, however some C++ applications have an undefined reference to std::nothrow. I found out that std::nothrow seems to be defined in libsupc++.a in the toolchain:

new_handler.o:
00000000 b (anonymous namespace)::__new_handler
00000000 T std::get_new_handler()
00000000 T std::set_new_handler(void (*)())
00000000 R std::nothrow

I make sure libsupc++.a is linked to my app. My app references std::nothrow as follow:

U nothrow

I guess the undefined reference happened due to mismatch b/w these names, one has namespace, the other has no namespace. How can I fix this namespace mismatch?

The following is my link command line:

arm-none-eabi-ld --entry=__start -nostartfiles -nodefaultlibs -g -Map=/usr/src/uros_ws/firmware/spresense/sdk/nuttx.map --cref --defsym __stack=_vectors+1572864 -T/usr/src/uros_ws/firmware/spresense/sdk/bsp/scripts/ramconfig.ld -L"/usr/src/uros_ws/firmware/spresense/sdk/lib" -L"/usr/src/uros_ws/firmware/spresense/sdk/bsp/board"  -L"/usr/src/uros_ws/firmware/spresense/sdk/bsp" \
-o "/usr/src/uros_ws/firmware/spresense/sdk/nuttx"   \
--start-group -lbsp -lsystem -lextdrivers -llte -lexamples -lapps -lsched -ldrivers -lconfigs -lc -lmm -larch -lcxx -lapps -lnet -lfs -lbinfmt -lgraphics -lnx -lcxx -lboard "/usr/local/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v7e-m/fpv4-sp/hard/libm.a"  -lsupc++ "/usr/local/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v7e-m/fpv4-sp/hard/libgcc.a" --end-group
1

There are 1 answers

0
Jose On

You'll have to rename the way you reference to nothrow in your app. A .a file is an already compiled library, so unless you are able to modify it and compile it again, it is non-modifiable (hence the symbols and references).

The compiler uses the namespace to create unique references (name mangling, check this example https://godbolt.org/z/cPkvxm). So you'll have to use std::nothrow (with the namespace it was defined), otherwise, you are calling another (and probably undefined) symbol.

If nothrow doesn't include a namespace, you would be able to use it as you are doing right now, however, if in the future you decide to create your own nothrown, you'll have a conflict (easy to solve, but it takes time and things like nothrownCustom/Customnothrown/nothrown_custom/etc instead of Custom::nothrown).

PD: using namespace for your whole file is a very easy fix, but have a look to this post before doing that: Why is "using namespace std;" considered bad practice?