У меня есть библиотека C++, которую я пытаюсь запустить в Mac OS X с помощью Clang. Библиотека состоит из библиотеки DLL и исполняемого файла Unit -Test. Он отлично компилируется с GCC и MSVC, с GCC я использую следующие настройки:
-fvisibility=hidden
__attribute__(visibility("default"))
std::runtime_error
. Все такие классы отмечены для видимости по умолчанию. Существует корневой класс LibraryException
, из которого выводятся более конкретные исключения.-std=c++0x
, с clang и библиотека, и исполняемый файл модульного теста построены с-stdlib=libc++ -std=c++11
В Mac OS X среда модульного тестирования теперь дает сбой, потому что исключения имеют неправильный тип. т.е.такой тест не проходит:
// bla.foo () throws CustomException, which is derived from LibraryException
TEST_THROWS (bla.foo (), CustomException)
// This works however
TEST_THROWS (bla.foo (), LibraryException)
Я проверил, что typeinfo и vtable моих пользовательских классов исключений экспортируются с использованием nm -g library.dylib | c++filt -p -i
. Кажется, это относится ко всем исключениям... что, черт возьми, здесь происходит? Я пытался отладить ошибки и вижу, что в библиотеке выдается правильный тип, но тот же тип не может быть обнаружен в исполняемом файле модульного теста. Требуется ли что-то особенное в Clang, чтобы это заработало? Я использую для тестирования последнюю версию googletest от SVN.
Небольшая тестовая программа демонстрирует ту же проблему :
try {
funcThatThrowsCustomExceptionFromLibraryDylib ();
} catch (CustomException& e) {
// doesn't get here
} catch (LibraryException& e) {
// does get here
// after demangle, this prints CustomException
// Can cast down to CustomException and access the fields as well
std::cout << typeid (e).name () << "\n";
}
. Это также дает сбой, например, когда из библиотеки выдается исключение boost::lexical_cast
.