I was recently going over calling conventions, ABI specs, etc, and in passing I recall reading about a requirement for executables/libraries to have only one typeinfo for a class.
With that in mind, my question is this: suppose two libraries libA.so
and libB.so
are linked statically against libboost_somethingorother.a
... each will have their own typeinfo for various classes in the boost library. How does the linker deal with this ambiguous situation? Or perhaps a more general question ought be asked: is it safe to statically link C++ libraries into a shared library?
To give a more concrete example
// in libC.a
class SomeException : public std::Exception { /* ... */ };
// in libA.so, links statically against libC.a
void A_test() {
extern void B_test();
try {
B_test();
}
catch( SomeException ) {}
// in libB.so, links statically against libC.a
void B_test() {
throw SomeException();
}
Is there anything unsafe about this?
It seems to me it must be doing "the right thing" whatever that is, since objects instantiated from header-only libraries can be safely used across code in 2+ shared libraries. However, I'm not confident enough in my logic, and I'm rather curious what I may've missed (if anything).
I finally got around to tinkering with this today. Assuming all conditions are met to emit a typeinfo object, the compiler emits it as a weak symbol. Because the symbols are weak, it'll always find the correct typeinfo object.
The compiler does not emit an undefined reference to the typeinfo object (at least, gcc 4.9 & clang 3.5 do not); it's all or nothing.