Reputation: 85
Will linking a static cpp lib and a dynamic cpp lib, both containing different versions of boost, violate ODR?
I am working on an iphone application. For final executable, I need to link a static library say libstatic1.a and a dynamic framwork say libdyanamic1.
libstatic1.a contains some version of boost, say boost 1.x and libdynamic1 contains another version of boost say boost 1.y. Now will final executable which links both of these, violate ODR rule?
Symbol visibility in libdynamic1:
I inspected symbols present in libdynamic1 using nm -g -C libdynamic1
and observed that symbols of boost threadpool and boost filesystem are present in the list.
If I am violating ODR, what are my options to handle the situation? (So far I have tested the executable on multiple devices and have not experienced any issue.)
Upvotes: 4
Views: 1977
Reputation: 15951
The standard only talks about "programs" where a "program" is a set of translation units "linked together", each consisting of a sequence of declarations [basic.link]. Arguing the ODR, which also concerns itself only with "programs", when it comes to questions involving dynamic libraries is not that straight forward. Since a "program" is required to contain a main
function [basic.start.main]/1, a dynamic link library will generally not qualify as a "program" on its own.
Strictly speaking, I think a dynamic library would have to be viewed as just another set of translation units that are "linked" with the rest to form the final program. Thus, the program would really only be complete once all images have been loaded into memory and dynamic linking is finished (run-time dynamic linking would seem to further complicate the matter, but can be ignored here I guess). In this sense, the program described in your question (linking both the static and the dynamic library where each is using a different version of boost) will almost certainly be violating the ODR since you are going to have multiple translation units which are, e.g., using different definitions of the same entities [basic.def.odr]/15.
In practice, however, this issue is highly platform- and toolchain-dependent. At the ABI level, you typically find that the types of linkage a symbol can have are more differentiated than what you find at the language level within C++. On Windows, for example, you typically have to explicitly specify which symbols should be exported when building a dynamic library, all names are internal to the library by default. On ELF-based Linux, on the other hand, that is famously not the case. It would seem, however, that you can use the -fvisibility=hidden
option to switch GCC to a more Windows-like default where your library will only export what you explicitly tell it to. Note that you must not have anything to do with boost in the interface your library exports as that will obviously lead to undefined behavior in your case…
Upvotes: 3