JAABIBP (Just Another ABI Blog Post)

ABI breakage is a hot topic. Let’s look at some ways C++ handles it, and how that compares to the WG14 _Alias proposal.

NOTE: This is probably the least educated article about ABI breakage yet. You should really watch Jason Turner’s youtube video or read JeanHeyd Meneide’s blog posts🙃

These views do not in any way represent those of NVIDIA or any other organization or institution that I am professionally associated with. These views are entirely my own.

After reading about transparent aliasing in this blog post from JeanHeyd Meneide, I had to play around with it in Godbolt and rave about its coolness on the Cursed Bird Site. Sean Parent rightly pointed out that this super neat proposal from JeanHeyd acomplishes pretty much the same thing as inline namespace in C++.



Let’s talk about that.

Problem Formulation

Let’s say you build executable A which dynamically links against library B.

Library B might look like this:

// B.hpp
namespace B {
int answer();
}

// B.cpp
#include <B.hpp>
int B::answer() {
  return 42;
}

while executable A might look like this:

#include <B.hpp>
#include <iostream>
int main() {
  std::cout << B::answer() << "\n";
  return 0;
}


Some time has passed since library B was released, and now the authors have decided that answer can be 30% faster if it uses long double instead of ints. How cool!

// B.hpp
namespace B {
long double answer();
}

// B.cpp
#include <B.hpp>
long double B::answer() {
  return 42;
}

Wow, so fast! 🚀

If you rebuild B without rebuilding A however, A will be expecting the answer’s return value to be an int (4 bytes on my system) even though B::answer now returns a long double (8 bytes on my system). When dynamically linking to the original B library, A unsurprisingly prints 42. When dynamically linking to the updated B library however, A prints the following:

$ ./A
83575344
$ # 😨 uh oh...

This disagreement between the program and the library at the binary level wreaks all sorts of havoc.

This section of JeanHeyd’s post gives a much better illustration.

Comparing inline namespace with _Alias and co

Why do some want to break it?

Q: Why don’t you just rebuild after an ABI change? A1: Are you rebuilding the standard library too? Many people will recommend not passing standard library types around, and not throwing exceptions across shared library boundaries. They often forget that at least one very commonly used shared library does exactly that… your C++ standard library.

On many platforms, there is usually a system C++ standard library. If you want to use that, then you need to deal with standard library types and exceptions going across shared library boundaries. If OS version N+1 breaks ABI in the system C++ standard library, the program you shipped and tested with for OS version N will not work on the upgraded OS until you rebuild.

  1. Binary Banshees and Digital Demons (JeanHeyd Meneide)
  2. To Save C, We Must Save ABI (JeanHeyd Meneide)
  3. Titus Winters paper on ABI
  4. Ben Craig’s Reddit post on ABI breakage
  5. Johnathan Wakely’s comment about ABI on Reddit
  6. Corentin’s blog post on ABI
  7. C++ Weekly - Ep 270 - Break ABI to Save C++

Written on Mar 14th, 2022