Недавно я перебирал соглашения о вызовах, спецификации ABI и т. Д., И попутно вспоминаю, как читал о требовании, чтобы исполняемые файлы / библиотеки имели только одну typeinfo для класса.
Имея это в виду, мой вопрос заключается в следующем: предположим, две библиотеки libA.so
а также libB.so
связаны статически против libboost_somethingorother.a
… у каждого будет своя собственная информация о типах для различных классов в библиотеке наддува. Как линкер справляется с этой неоднозначной ситуацией? Или, возможно, следует задать более общий вопрос: безопасно ли статически связывать библиотеки C ++ в общую библиотеку?
Чтобы дать более конкретный пример
// 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();
}
Есть ли что-нибудь небезопасное в этом?
Мне кажется, что он должен делать «правильные вещи», что бы это ни было, поскольку объекты, созданные в библиотеках только для заголовков, могут безопасно использоваться в коде в 2+ разделяемых библиотеках. Тем не менее, я недостаточно уверен в своей логике, и мне довольно любопытно, что я мог упустить (если что-нибудь).
Я наконец-то нашел время поработать с этим сегодня. Предполагая, что выполнены все условия для выдачи объекта typeinfo, компилятор выдает его как слабый символ. Поскольку символы слабы, он всегда найдет правильный объект typeinfo.
Компилятор не выдает неопределенную ссылку на объект typeinfo (по крайней мере, gcc 4.9 & лязг 3.5 нет); это все или ничего.