[cfe-dev] Proposal: Managing ABI changes in libc++

Marshall Clow mclow.lists at gmail.com
Mon Dec 8 07:42:17 PST 2014


In general, we try to avoid making changes to the ABI for libc++.
ABI changes can lead to subtle, hard to find bugs, when part of a piece of software (a dylib or static library, say) is build to the old ABI, and the rest to the new ABI. People have been burned in the past by inadvertent changes to the libc++  ABI. (not to be confused with the libc++abi project)

Eric Fiselier has been working on a tool to detect ABI changes, so that (hopefully) all future changes will be intentional.

ABI-breaking changes can include things like:
	* Changes to structures (sizes, layout)
	* Addition/removal of virtual functions (vtable layouts)
	* Changes to template parameters (addition, removal)

Also, there are times that a change to the standard will mandate an ABI change. I tend to argue against those in the committee meetings, but I don’t always get my way.

In the LLVM community, there are two differing opinions about changes in lib++ that are ABI-breaking. Broadly speaking:

a) There are the people who ship libc++ in production systems, who say: Whoa! Don’t do that! Ever! (or at least “let us decide when”).

b) There are the people who use libc++ internally, who say: Is it faster? Does it work better? Do it!

=== Proposal ===

Goals:
1) Make the default be “ABI is stable” (modulo changes in the C++ standard)
2) Make it possible for people to propose (and use) ABI-breaking changes for libc++, and have them live in tree.
Note: This would make it possible, not trivial. We still want to avoid gratuitously changing the ABI. 

Concrete steps:
1) Give each ABI-breaking change its own "enabling macro”, that starts with “_LIBCPP_ABI_”

We have an example of this today. There are two different std::basic_string layouts defined in <string>, and the
second (ABI changing) one is controlled by the macro _LIBCPP_ALTERNATE_STRING_LAYOUT

Under my proposal, I would change this to _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT, and keep the old name as a synonym.

2) Create a global macro “_LIBCPP_ABI_UNSTABLE” which, when defined, turns on ALL of the _LIBCPP_ABI_* changes.

Adding a new, ABI-incompatible change to the library would consist of:
* Choosing an enabling macro name of the form _LIBCPP_ABI_XXXXXXX
* Wrapping the code in #ifdef _LIBCPP_ABI_XXXXXXX
* Enabling the macro if _LIBCPP_ABI_UNSTABLE is defined.

I think that this convention will make it possible both camps ((a) and (b) above) to coexist in the same code base.

Comments?

— Marshall

P.S.	There are currently three bugs/feature request in the bug tracker that would require ABI changes to implement.

* Bug 17980 - Container<Incomplete Type> support
* Bug 19153 - Some iterators non-standard
* Bug 21715 - 128-bit integers printing not supported in stl implementation








More information about the cfe-dev mailing list