<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">My apologies as well for the delay.  Chandler's response was quite excellent, so I'm going to piggy back on his comments.</div><br class=""><div><blockquote type="cite" class=""><div class="">On Dec 19, 2014, at 6:28 PM, Chandler Carruth <<a href="mailto:chandlerc@google.com" class="">chandlerc@google.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">First, sorry for delays. I do owe you feedback here though, and then I'll go look at the patch. =]<div class="gmail_extra"><br class=""><div class="gmail_quote">On Mon, Dec 8, 2014 at 7:42 AM, Marshall Clow <span dir="ltr" class=""><<a href="mailto:mclow.lists@gmail.com" target="_blank" class="">mclow.lists@gmail.com</a>></span> wrote:<br class=""><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">In general, we try to avoid making changes to the ABI for libc++.<br class="">
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)<br class="">
<br class="">
Eric Fiselier has been working on a tool to detect ABI changes, so that (hopefully) all future changes will be intentional.<br class="">
<br class="">
ABI-breaking changes can include things like:<br class="">
        * Changes to structures (sizes, layout)<br class="">
        * Addition/removal of virtual functions (vtable layouts)<br class="">
        * Changes to template parameters (addition, removal)<br class="">
<br class="">
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.<br class="">
<br class="">
In the LLVM community, there are two differing opinions about changes in lib++ that are ABI-breaking. Broadly speaking:<br class="">
<br class="">
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”).<br class="">
<br class="">
b) There are the people who use libc++ internally, who say: Is it faster? Does it work better? Do it!<br class=""></blockquote><div class=""><br class=""></div><div class="">(FWIW, there are also people that support users in both camps (a) and (b). I'm one of those.)</div><div class=""> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br class="">
=== Proposal ===<br class="">
<br class="">
Goals:<br class="">
1) Make the default be “ABI is stable” (modulo changes in the C++ standard)<br class="">
2) Make it possible for people to propose (and use) ABI-breaking changes for libc++, and have them live in tree.<br class="">
Note: This would make it possible, not trivial. We still want to avoid gratuitously changing the ABI.<br class="">
<br class="">
Concrete steps:<br class="">
1) Give each ABI-breaking change its own "enabling macro”, that starts with “_LIBCPP_ABI_”<br class="">
<br class="">
We have an example of this today. There are two different std::basic_string layouts defined in <string>, and the<br class="">
second (ABI changing) one is controlled by the macro _LIBCPP_ALTERNATE_STRING_LAYOUT<br class="">
<br class="">
Under my proposal, I would change this to _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT, and keep the old name as a synonym.<br class="">
<br class="">
2) Create a global macro “_LIBCPP_ABI_UNSTABLE” which, when defined, turns on ALL of the _LIBCPP_ABI_* changes.<br class="">
<br class="">
Adding a new, ABI-incompatible change to the library would consist of:<br class="">
* Choosing an enabling macro name of the form _LIBCPP_ABI_XXXXXXX<br class="">
* Wrapping the code in #ifdef _LIBCPP_ABI_XXXXXXX<br class="">
* Enabling the macro if _LIBCPP_ABI_UNSTABLE is defined.<br class="">
<br class="">
I think that this convention will make it possible both camps ((a) and (b) above) to coexist in the same code base.<br class="">
<br class="">
Comments?<br class=""></blockquote><div class=""><br class=""></div><div class="">As far as this goes, I'm 100% in favor.</div></div></div></div></div></blockquote><div><br class=""></div><div>I'm supportive of this initiative; my main concern is the social aspect that we have a manageable way to discern different ABI configurations and that they are all testable.</div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote"><div class=""><br class=""></div><div class=""><br class=""></div><div class="">I think there are two more ABI concerns that we should really figure out a plan for now in order to ensure they fit cohesively with the whole.<br class=""></div><div class=""><br class=""></div><div class="">1) I think we need a way to more quickly roll standard-mandated or bug-fix ABI breaks into something much more stable than "unstable".</div><div class="">2) I think we need to figure out how to maintain at least two stable ABIs at the same time.</div><div class=""><br class=""></div><div class="">I'll expand a bit below.</div><div class=""><br class=""></div><div class="">A terminology point, when I say a "minor" or "major" ABI break, I am not classifying the *nature* of the break, but the *scope*. Changing the layout of std::string has a radically different scope in its impact than fixing the return type of a infrequently used function for example.</div><div class=""><br class=""></div><div class="">For (1), let's consider two cases.</div><div class="">1.1) We introduce an ABI-significant bug and need to fix it. What do we do? This is exacerbated when the bug has shipped to customers. Some users of libc++ update *very* rapidly, and so even with a very narrow window of fallout in-tree, it would be advantageous in my opinion to have a non-silent way to fix these issues. Note that this only really applies to minor ABI breaks. A massive breaking change would be sufficiently disruptive to warrant more extreme measures and I certainly hope i</div><div class="">1.2) The standard changes in some *minor* way that necessitates an ABI break. Note that I'm not talking about "C++1z requires a whole new ABI" kind of break, I'm talking about the standard equivalent to 1.1 -- we ship a bug, we fix it, but it requires some small ABI break.</div><div class=""><br class=""></div><div class="">In both of these cases, I think the right thing for the default configuration of libc++ is to make the change and take the ABI break. I think we should be standard conforming and correct above all else out of the box. But I think it is important to provide some mechanism to opt *out* of such changes to the ABI, at least in order to control when they arrive in systems that are very susceptible to ABI fallout.</div></div></div></div></div></blockquote><div><br class=""></div><div>This seems reasonable to me, and provides an option for vendors to curate the ABI based on their particular needs.</div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote"><div class=""><br class=""></div><div class="">For (2), my motivation is to chart out a path forward, likely measured in years if not decades. This would include the ability to follow any massive upheaval in the standard's ABI, as well as the ability to pick up improvements which go in under the unstable bucket after a resonable interval and in a way that platform vendors are comfortable with. I picked "two" specifically for a reason. I think we should be able to create a new stable major ABI without changing the default while customers test and evaluate it, etc. Then we should be able to switch the default at some point without ever touching the old ABI. Finally, after some lengthy period (likely also measured in years if not decades) we should be able to remove the old ABI and start the process again. When Howard first discussed the time scale at which this kind of breaking change could possibly be acceptable to customers, he used decades. I'm echoing that, as it matches my experience with customers that have hard ABI requirements.</div></div></div></div></div></blockquote><div><br class=""></div><div>I like this goal as well.  I'm concerned about the practicalities of being able to manage such divergences in the libc++ project in a coherent way, but I think it really comes down to the scale of the changes we are talking about as well as the time scale.</div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote"><div class=""><br class=""></div><div class="">So, here is my initial proposal for how to handle the above two issues.</div><div class=""><br class=""></div><div class="">First, extend the ABI definitions to include what they already (somewhat) do: versions. Specifically, both minor and major versions to handle the above two use cases respectively. We already sort-of have this for the stable ABI, I just think we should formalize it, document it, and incorporate it into the macro naming convention.</div><div class=""><br class=""></div><div class="">The resulting pattern would be that when a bug-fix or minor standards-motivated change is introduced which breaks the ABI, it too is guarded behind an ABI macro, but that macro is by-default enabled. A new high-level macro (i'm trying to avoid picking names here, I suspect Marshall will pick better ones than I will) would be introduced to restrict libc++ to the prior minor ABI version, and that macro would disable the bug-fix. If at some point a contributor wants to build a new major version stable ABI out of a sub set of the unstable changes in the tree (and everyone agrees that is reasonable to do), then the expected new high-level macros for those versions would be introduced, and the per-feature abi-breaking macros would be flipped based on them.</div><div class=""><br class=""></div><div class="">Does this make sense to folks?</div></div></div></div></div></blockquote><div><br class=""></div>This makes sense to me.</div><div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote"><div class=""><br class=""></div><div class=""><br class=""></div><div class="">One goal I have throughout this is that we *have* per-feature ABI-break macros, but that users essentially never need to use them. I would like to have something closer to version numbers that they interact with in order to request specific sets of features that can be documented together.</div></div></div></div></div></blockquote><br class=""></div><div>I very much like this goal as well.</div></body></html>