Ticket #5170 (closed Feature Requests: fixed)
Some local functions have external linkage
|Reported by:||Luke Moore <luke.moore@…>||Owned by:||anthonyw|
|Milestone:||To Be Determined||Component:||thread|
|Version:||Boost Development Trunk||Severity:||Problem|
The thread_proxy and tls_destructor functions in libs/thread/src/pthread/thread.cpp have external linkage (the symbols are exported in the final library). However, these functions are only intended for use inside this compilation unit. Similar functions in once.cpp also have unintended external linkage, and potentially others in other areas of boost. A consequence of these symbols being visible is that it's hard to use two different versions of boost.Thread in the same binary, even when one of the versions of boost has been wrapped in a namespace to avoid name collisions. The name collisions still occur for thread_proxy, tls_destructor, and the others because they are declared as extern "C", so their names are not mangled.
It may seem unusual to attempt to use two different versions of boost in the same program, but it is a scenario our customers are running into more and more often and I'd like to give some explanation of why it happens. As more development projects start to use boost, more libraries start to link against it. A program that attempts to use multiple of those libraries won't work if they use different versions of boost. When one or more of these libraries is available in binary form and not source form, it is difficult to ensure the boost versions match. As a result, our customers attempt to version boost's symbols themselves for the boost version they use by compiling a version of boost wrapped in a namespace. Unfortunately, symbols from extern "C" functions are not versioned.
The thread_proxy, tls_destructor, etc., functions in question need to be declared as extern "C" since they are passed as callbacks into the pthreads library, and the calling conventions for C and C++ may differ on some platforms ( http://lists.boost.org/Archives/boost/2011/01/175910.php).
Prior to revision 40424, these functions were declared as static. However, in revision 40424 the static specifier was removed and they were put inside an unnamed namespace. However, despite the claim at http://stackoverflow.com/questions/2594178/why-do-you-need-extern-c-for-c-callbacks-to-c-functions that "[the extern "C" function] is in an unnamed namespace, and not accessible outside the translation unit.", these functions do have external linkage, at least on g++ Linux systems. The bug at http://gcc.gnu.org/bugzilla/show_bug.cgi?id=28409 mentions that "extern C should make the function have external linkage in the object file. Namespaces have no impact on extern "C" functions, except from the point of view of lexical scoping", and this can be confirmed by looking for thread_proxy in the output of nm -D.
It it possible to please add back the static specifier to the extern "C" functions in question? Attached is a patch file showing the proposed changes.
- Status changed from new to closed
- Resolution set to fixed