Search code examples
c++linkershared-librariesstatic-librariestypeinfo

How does the linker deal with unique typeinfo constraint for C++ static libraries linked into shared libraries?


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).


Solution

  • 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.