There are 2 software teams developing C++ applications for the same OS (Scientific Linux 6.5):
Team_A uses the OS provided compiler and libraries (GCC 4.4.7, GLIBC_2.12, GLIBCXX_3.4.13), to build its C++98 application and various shared libraries.
Team_B uses a newer GCC version (4.8.3) which has been built from source. It's a native compiler, it links against the OS libc, and uses the OS standard headers, but has its own version of stdc++ (GLIBCXX_3.4.19). Team_B uses this compiler in C++11 mode to build its application (AppB), and deploys libstdc++ and libgcc_s along with it.
Team_A provides services to Team_B in form of a shared library (.so, .hpp): LibA. The API of the library is a set of C++ classes (declaration in the header, implementation in the .so), and the methods take std::string and other stdc++ classes as arguments.
At this point we arrive to the problem: AppB constructs GLIBCXX_3.4.19 C++11 style std::whatever objects and passes them to LibA who interprets them as GLIBCXX_3.4.13 C++98 style objects, and this might not be forward compatible.
Is this a problem? Can it lead to an application crash? Are the std::whatever implementations compatible among versions (same memory layout)? What about c++98 vs C++11?
Some plot twists which make me more confused:
I would like to understand what's exactly happens in this case, if it is risky, and void problems. Getting the teams on the same development environment is not an option. Removing std:: classes from the API would also be very hard to make.
Any pointers welcome! :)
clang, modulo bugs, is fully C++ ABI compatible with GCC (they both follow the intervendor Itanium ABI) on unix systems. Make sure you use the same standard library for all components because libstdc++ and libc++ are different implementations with completely different object layouts.
The two implementations are not link-compatible (they have different mangled names, so can't be linked together) but can co-exist in the same binary (they have different mangled names, so don't conflict if one object uses std::string and the other uses std::__cxx11::string ).
These details are defined as the compiler Application Binary Interface, or ABI. From GCC version 3 onwards the GNU C++ compiler uses an industry-standard C++ ABI, the Itanium C++ ABI. The GNU C++ compiler, g++, has a compiler command line option to switch between various different C++ ABIs.
Unlike C, there is no defined ABI for C++. That means ....
protected:
, private:
and public:
parts of the structure. The location and meaning of the vtable may be moved between compilers. There may be different pre-defined functions such as the typeinfo in the vtable between the different compiler versions.What can you do to mitigate these problems?
Instead of providing a compiled library, deliver the services as source code to be compiled on the same environment.
The source built compiler, can be re-built with the older stdC++. This would limit the impact of point 3).
There is an interface between the two teams, which needs to speak a common language. This language probably ought to be C.
Team A => C++ facade/stub => C interface => C++ facade/proxy => Team B.
The facade should be built in the environment where it will be used.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With