3

There are dynamic libraries provided by others, which are out of my control. What I know is that most of the aforementioned libraries are compiled by g++4.9.4 & g++4.8.4 with C++11 support, and few libraries are compiled by g++11.1.0 with C++14 support. And I have to use newer g++ which supports C++17 to compile my project. I intend to use g++11.3.0 on Ubuntu20.4.

Is there any potential problem I should be aware of when linking to dynamic libraries compiled by the said old version g++?

John
  • 2,963
  • 11
  • 33

2 Answers2

3

TL;DR: the dynamic library linkage you describe should "just work", provided you link the executable using the newer version of g++.

Both versions of GNU g++ you mention use libstdc++ (specifically libstdc++.so.6.0.*) to implement the support libraries needed for C++11/C++17.

For the most part, newer versions of libstdc++ maintain what their ABI policy manual calls "forward compatibility":

Versioning gives subsequent releases of library binaries the ability to add new symbols and add functionality, all the while retaining compatibility with the previous releases in the series. Thus, program binaries linked with the initial release of a library binary will still run correctly if the library binary is replaced by carefully-managed subsequent library binaries. This is called forward compatibility.

There are a few caveats, for unusual cases (which are probably irrelevant to your situation):

  1. This assumes all the objects are built with compatible CPU ABI/architecture flags (i.e. -march, -mcpu, -m64, etc. if any), which is a general requirement for correctly linking libraries together (regardless of compiler version). The compiler defaults for these options should select compatible settings for your system, so this challenge usually only arises with cross-compilation scenarios where you've deliberately changed to a non-default ABI.
  2. The internal representation of some C++ library classes (eg std::string, std::list) have changed over time, which can lead to problems if two libraries are sharing access to the same C++ object. This should only be a problem if you pass C++ library objects or references to them across the library interface where the g++ version differs.
Dan Bonachea
  • 2,408
  • 5
  • 16
  • 31
  • 1
    **1**Thank you for the detailed explanation. How to understand *Of course this assumes all the objects are built with compatible CPU ABI/architecture flags (i.e. -march, -mcpu, -m64, etc. if any), but **that is probably irrelevant to your situation.*** in the right way? Why do you say the said flags is irrelevant? Could you please explain that in details for me? I think the different flags(say `-march`, `-mcpu`, `-m64` ) for the separate libraries may lead some potential problems. **2**. How/Where do you find out that Both versions of GNU g++ you mention use libstdc++.so.6.0.*? – John Nov 07 '22 at 01:50
  • 2
    ***3***. As you mentioned `libstdc++`, what about `libc`, `libgcc_s`,`librt`,`libm`,`libpthead`?I found the said libraries compiled by old version g++ depend on these libraries(say `libc`). – John Nov 07 '22 at 02:00
  • @John The`-march`, `-mcpu`, etc flags determine the ABI in use, and all the objects in an executable need to use a compatible ABI. Normally these flags will be automatically set to default values matching your system, so unless you've deliberately set them to non-default values (e.g. for cross-compilation) they should default to a compatible ABI. – Dan Bonachea Nov 07 '22 at 02:24
  • @John "Both versions of GNU g++ you mention use libstdc++.so.6.0.*" - see [this section of the linked ABI policy manual](https://gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html#:~:text=GCC%204.8.3%3A%20libstdc,libstdc%2B%2B.so.6.0.20) – Dan Bonachea Nov 07 '22 at 02:26
  • @John "what about `libc, libgcc_s,librt,libm,libpthead`" - `libgcc_s.so` is provided by the newer g++ compiler, and follows a similar "forward compatibility" policy as libstdc++. The other libraries you mention should all be provided by the Linux OS distro (e.g. in `/usr/lib64`) and have nothing to do with the g++ version in use. – Dan Bonachea Nov 07 '22 at 02:29
2

Versions of gcc before 5.1 did not fully support C++11. They could not possibly. The ABI needed to support C++11 was not ready.

See this article for more information.

If you have object files compiled with gcc <5.1 and object files compiled with gcc >=5.1 (on default ABI settings), and they somehow share data that contain std::string and/or std::list objects, then they cannot work together. You need to recompile at least some of them.

In many cases you will get linker errors, and in some other (rare) cases the program will compile, link, and have mysterious crashes at run time. You probably should not worry about these cases as they are unlikely to occur naturally with normal libraries.

If there are no shared std::string or std::list involved, then you might be able to get away with it. However there are corner cases.

If you have a shared library dynamically linked with libstdc++.5.x. and another one dynamically linked to libstdc++.6.x, the final executable will be indirectly linked with both. This could be a problem in some cases. Try LD_PRELOADing one or the other to establish precedence.

n. m. could be an AI
  • 112,515
  • 14
  • 128
  • 243
  • 1
    ""*If you have object files compiled with gcc <5.1 and object files compiled with gcc >=5.1, and they somehow **share** data that contain std::string and/or std::list objects...*" ***Here*** is my understanding of the ***share***: If the `std::string` & `std::list` is only used in the implementation of the library, the interface of the library is a C interface. And the aforementioned library is compiled with `4.9.4`. If I understand you correctly, there is no potential problem if a binary program is compiled with `g++11.0.3` and is linked to the said library. Am I right? – John Nov 07 '22 at 08:15
  • If the std::string & std::list are only used in the implementation of the library, then their instances are definitely not shared. However there are additional issues, I will add them later today. – n. m. could be an AI Nov 07 '22 at 09:12
  • 1
    Thank you for the detailed explanation. I my case, the libraries compiled with `4.8.4` or `4.9.5` are still linked to `libstdc++.6.x` other than `libstdc++.5.x`. Here is the related information: `readelf -d libops.so | grep Shared | grep libstdc++` outputs `libstdc++.so.6` and `readelf -p .comment libautooms.so` outputs `[ 0] GCC: (Ubuntu 4.9.4-2ubuntu1~14.04.1) 4.9.4 [ 2b] GCC: (Ubuntu 4.9.4-2ubuntu1~16.04) 4.9.4 [ 54] GCC: (Ubuntu 4.8.4-2ubuntu1~14.04.4) 4.8.4` – John Nov 07 '22 at 11:26