Dual ABI issues
The concept of Dual ABI, as introduced by the GCC (GNU Compiler Collection) 5.1 release for its libstdc++ library, revolves around supporting two Application Binary Interfaces (ABIs) simultaneously.
This detailed explanation will unpack the concepts and technical terms involved in understanding Dual ABI, its implementation, and its impact on C++ development.
What is ABI?
An Application Binary Interface (ABI) is a low-level, binary interface between two program modules; one of which could be a library or an operating system.
It defines details such as how functions are called and how data is formatted in memory.
An ABI ensures that a program compiled by one compiler can call and use functions compiled by another compiler, provided both compilers adhere to the same ABI.
Background and Need for Dual ABI
With the release of the C++11 standard, certain changes were mandated to standard library components, such as std::string
and std::list
, to enhance performance and conformance to the new standard. For example:
Copy-On-Write (COW) Strings: The C++11 standard prohibits the use of COW for
std::string
due to thread safety and performance issues.List Size Tracking:
std::list
is required to keep track of its size, changing its implementation.
To comply with these changes without breaking existing binaries linked against older versions of libstdc++, GCC introduced a Dual ABI mechanism.
Implementation of Dual ABI
Inline Namespaces: The new implementations of affected components (like
std::string
andstd::list
) were placed in an inline namespace (std::__cxx11
), allowing both old and new versions to coexist in the same library. This means, for example, that the newstd::list
is actuallystd::__cxx11::list
._GLIBCXX_USE_CXX11_ABI Macro: This macro controls which ABI (old or new) is used by the source file being compiled. Setting it to
1
uses the new ABI, while setting it to0
uses the old ABI.
Choosing the ABI
The decision of which ABI to use is made at the compilation level, independent of the C++ standard version (-std=c++11
, -std=c++03
, etc.) being used. This design choice allows for linking code compiled with different C++ standards but ensures ABI consistency.
Impact on Code
Extensive Use of
std::string
: Becausestd::string
is a fundamental part of the C++ standard library, the Dual ABI affects many other types, including I/O streams and locale facets.Exception Handling: Most standard exceptions do not change with the ABI to ensure exceptions thrown in one part of a program can be caught in another, regardless of the ABI used. However,
std::ios_base::failure
is an exception due to changes in its base class in C++11.
Troubleshooting and Compatibility
Linker Errors: When attempting to link object files compiled with different ABIs, you may encounter linker errors related to
std::__cxx11
namespace symbols. This usually indicates ABI incompatibility.Third-party Libraries: If a third-party library was compiled with an older ABI, you might need to compile your code with the old ABI for compatibility.
Last updated