<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="">Hi guys,<div class=""><br class=""></div><div class="">We want to share implementation details between <font face="Courier" class="">std::function</font> and its new cousins which we are designing. A program which targets a <font face="Courier" class="">class foo</font> by <font face="Courier" class="">std::function<void()></font> shouldn’t pay the same price a second time when it initializes a <font face="Courier" class="">std::unique/movable_function<void()></font> with a <font face="Courier" class="">foo</font> as well. However, we also don’t want to use exactly the same erasure class for both wrappers, because then <font face="Courier" class="">unique_function</font> would instantiate copy constructors it cannot use, representing a different kind of bloat.</div><div class=""><br class=""></div><div class="">The solution is to share some functions between similar templates. This might violate libc++’s ABI standards, or it might not. Internal functions, including erasure methods, are declared using this macro:</div><div class=""><div class=""><br class=""></div><div class=""><font face="Courier" class="">#define _LIBCPP_INLINE_VISIBILITY __attribute__ ((__always_inline__))</font></div><div class=""><br class=""></div><div class="">The idea is that it’s dangerous for a function to be exported from a DLL, then vanish in a subsequent version at the whim of the inliner. A function which is always inlined will never be visible in the first place. This stabilizes not only libc++.dylib, but also user libraries with respect to the standard library.</div></div><div class=""><br class=""></div><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 class=""><br class=""></div><div class="">Introducing new-but-similar specializations to the the vtable-polymorphic erasure class is making me confused.</div><div class=""><br class=""></div><div class=""><ol class="MailOutline"><li class="">Is it OK at all that shared libraries tend to export standard erasures? Or is this all a giant bug requiring a ground-up rewrite? (I’ve not dug into the history.)</li><li class="">If OK, should shared functions dominated by the vtables of several specializations be marked <font face="Courier" class="">__noinline__</font>? (Such a function is unreachable except through a vtable, which is already exported.) Is there some macro or protocol for this?</li><li class="">I’m spending this effort optimizing a case without first analyzing it. Has libc++ already decided whether to care about <font face="Courier" class="">std::function</font> overhead, or should I just make fully-independent specializations and be through with it? Is there a known, quantified margin of headroom?</li></ol><div class=""><br class=""></div></div><div class="">Regarding #2, why does the virtual function <font face="Courier" class="">std::__function::__base::~__base</font> have inline visibility? Yes, it’s called directly by the derived class destructor, but that is only accessible by a vtable. Is there some potential ABI error if it omitted the visibility spec, or is it just erring on the side of caution? (All the other virtual functions omit the spec.)</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>- Thanks much,</div><div class=""><span class="Apple-tab-span" style="white-space:pre">    </span>David</div></body></html>