[cfe-dev] Erasures and bloat vs. ABI stability
potswa at gmail.com
Sun May 24 22:37:09 PDT 2015
> On 2015–05–21, at 5:30 PM, David Krauss <potswa at gmail.com> wrote:
> The danger, but not the solution, also applies to vtables. If libc++ (or another library) uses a polymorphic class, then it’s committed to exporting it forever. The erasures of std::function are implemented using vtables, but this isn’t the only possible approach. libstdc++ uses switch statements instead.
Marking the class std::__function::__func as _LIBCPP_HIDDEN looks like an easier alternative. I’m not sure I’m testing the idea correctly, but it seems to work. Setting this attribute causes different shared libraries to see different classes. Armed with this, erasure specializations cleanly hide their internal workings from the ABI, exposing only the base-class vtable layout.
Already, without the attribute, each shared library internally refers to its own vaguely-linked copies of the vtables, which point to local, vague copies of the functions. The issue seems subtler than I made it out to be. An executable won’t cease to load when a specialization disappears from a shared library, nor could an object ever see functions called from the wrong vtable. The difference is maybe only that instances claim to be of the same dynamic type according to typeid, dynamic_cast, and throw, but that doesn’t ever actually come up. I might be missing something though. (I’ve disproven my theory of why the destructor is _LIBCPP_INLINE_VISIBLITY but the other virtual members aren’t, so that’s once again a mystery.)
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the cfe-dev