1

Our C++ application, running on Linux and compiled with gcc, loads dynamic libraries as 'plugins'. The code is well-established and runs fine with gcc 5.3.1. However, with gcc 7.3.0, library loading is failing at runtime. We get 'symbol not found' errors such as:

Failed to load <snip>/solibs/_gnuRelease/libLink.so
dlerror = <snip>: undefined symbol: _ZN24ChannelSelection7INVALIDE ( ChannelSelection::INVALID )
Failed to load <snip>/solibs/_gnuRelease/libBitTrue.so
dlerror = <snip>: undefined symbol: _ZTIN8StarLibs7LinkSim8StarFPGAE ( typeinfo for StarLibs::LinkSim::StarFPGA )

(Demangled symbol name is in parentheses).

Has anything changed in gcc 7.3.0 that might cause this?

7
  • 2
    Maybe the obvious question first: are those symbols actually present in your .so files?
    – Botje
    Commented Dec 6, 2018 at 10:31
  • Yes, sorry that is the obvious question. So for missing symbol _ZN24ChannelSelection7INVALIDE, that symbol is not in the library file for gcc 5.3 and 7.3 builds, build only the 7.3 build complains about it. The actual definition of the symbol is static const int INVALID = -1; Could there something special about a static symbol that is causing a problem?
    – DavidA
    Commented Dec 6, 2018 at 10:59
  • From what I could find, what you are seeing is not bound to the compiler per se, but how the constant is used, eg in the standard library. GCC 6 started compiling code as C++14 by default, which may enable a different overload that needs the address of your constant (const int&, for example). Short version: Can you try compiling your code with -std=gnu++98, which was the pre-GCC6 default?
    – Botje
    Commented Dec 6, 2018 at 12:03
  • I have tried -std=gnu++98 and the build works ok. So, as you predicted, it is related to C++11 or C++14 being used. Not sure what to do about it. I do want to use C++11 later.
    – DavidA
    Commented Dec 6, 2018 at 12:10
  • If you can jump directly to C++17, you can declare your static const ints as constexpr or inline and the compiler will generate it with external linkage (defining a symbol). Until then, you can choose to explicitly provide symbols in a .cpp file like so: const int ChannelSelection::INVALID;
    – Botje
    Commented Dec 6, 2018 at 12:20

1 Answer 1

0

If you can jump directly to C++17, you can declare your static const ints as constexpr or inline and the compiler will generate it with external linkage (defining a symbol).

Until then, you can choose to explicitly provide symbols in a .cpp file like so:

const int ChannelSelection::INVALID;

Not the answer you're looking for? Browse other questions tagged or ask your own question.