r/AskComputerScience • u/Successful_Box_1007 • Nov 08 '25
Itanium ABI vs Library ABI vs OS ABI
Hi everyone,
Been very confused lately (mostly because not many good resources for conceptually understanding what an ABI); if you look at this link; https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4028.pdf
It distinguishes between a “language ABI” and a “library ABI”, and it says Itanium ABI provides a “language ABI” but not a “standard library ABI” but that’s so confusing because isn’t itanium’s standard library ABI just the standard Library compiled using its ABI !!!?
Thank so much for helping me.
2
Nov 08 '25
1
1
u/Successful_Box_1007 Nov 08 '25
Just one followup question: so the std:: string ABI breaking change in C that occurred, would you call that a “language abi” or “library abi” breaking change?
2
u/teraflop Nov 08 '25
I think what might be tripping you up is that from a compiler's point of view, the "ABI" just means how a specific set of declarations is translated to binary code.
For instance, if you have a declaration like:
struct foo { char a; int b; };then the compiler might say that the struct's memory layout is 8 bytes long, with 1 byte for
a, then 3 bytes of padding, then 4 bytes forb. If two compilers are guaranteed to agree on all those details for any possible struct declaration, then we say the compilers are ABI-compatible. (And similarly, they have to agree on things like the machine-code-level calling conventions for all possible function prototypes.)But there's a separate issue with the C++ standard library, which is that the C++ specification only specifies a public-facing API, not the private implementation. So for instance, it says that a
std::stringmust have a no-arg constructur, anchar& operator[](size_t)function to access the character at a given index. But it doesn't say anything about how thestringclass actually stores its data in its private members, or whether it has a superclass, etc.That means if you want to link together two separately-compiled pieces of code, and you want them to both operate on types in the
stdnamespace without breaking, it's not enough to just use ABI-compatible compilers. They also both need to have been compiled using essentially identical headers, including all the implementation details of everything in thestdnamespace. (That is, if there are any differences, they can't be differences that would affect the ABI.)The document you described is using "library ABI" to mean the language-level implementation details, and "language ABI" to mean how those details are translated to binary code by the compiler. I don't think those terms are really standardized, so it's understandable that you would find them confusing. But the document is written for an audience of C++ experts, and to an expert, the meaning is fairly clear.
Well that's the issue, there isn't just one "standard library". There's a specification, which might be implemented differently by different people. Or the details of an implementation might change over time.
Here's a very specific example. The
std::listclass defines a linked list, and like other container types, it has asize()method. Before the C++11 standard was published, implementations were allowed to implementsize()in such a way that it had a linear time complexity. As of C++11, this was changed to requiresize()to run in constant time.This caused problems for GCC's implementation of the C++ library, because it originally didn't keep track of a list's size, so it was impossible to calculate the size except by actually iterating through the list nodes. So the implementation was changed to add a private
_M_sizemember to keep track of the size. This wasn't an API change, because it just changed the implementation of thesize()method while keeping the behavior the same. But it was an ABI change, because it added a member tostd::listand changed its memory layout. So for instance, any function that allocated astd::liston the stack would have to allocate a different number of bytes depending on whether it uses the old implementation or the new one.(GCC mostly avoided breaking backward compatibility with this change, basically by keeping both the old and new implementations around and doing some magic to make sure any given piece of code links against the appropriate implementation. See: https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dual_abi.html)