<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=""><br class=""><div><blockquote type="cite" class=""><div class="">On 2015–05–21, at 5:30 PM, David Krauss <<a href="mailto:potswa@gmail.com" class="">potswa@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">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 <font face="Courier" class="">std::function</font> are implemented using vtables, but this isn’t the only possible approach. libstdc++ uses <font face="Courier" class="">switch</font> statements instead.</div></div></div></blockquote><br class=""></div><div>Marking the class <font face="Courier" class="">std::__function::__func</font> as <font face="Courier" class="">_LIBCPP_HIDDEN</font> 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.</div><div><br class=""></div><div>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 <font face="Courier" class="">typeid</font>, <font face="Courier" class="">dynamic_cast</font>, and <font face="Courier" class="">throw</font>, but that doesn’t ever actually come up. I might be missing something though. (I’ve disproven my theory of why the destructor is <font face="Courier" class="">_LIBCPP_INLINE_VISIBLITY</font> but the other virtual members aren’t, so that’s once again a mystery.)</div></body></html>