g ++ неопределенная ссылка на typeinfo - PullRequest
184 голосов
/ 21 ноября 2008

Я только что наткнулся на следующую ошибку (и нашел решение в сети, но его нет в переполнении стека):

(. Gnu.linkonce. [Stuff]): не определено ссылка на [метод] [объект файл] :( gnu.linkonce [материал])..: неопределенная ссылка на `typeinfo для [Имя_класс]

Почему можно получить одну из этих ошибок компоновщика "неопределенная ссылка на typeinfo"?

(Бонусные баллы, если вы можете объяснить, что происходит за кулисами.)

Ответы [ 16 ]

3 голосов
/ 16 декабря 2014

Я получил много этих ошибок только сейчас. Случилось так, что я разделил класс только для заголовочного файла на заголовочный файл и файл cpp. Однако я не обновил свою систему сборки, поэтому файл cpp не был скомпилирован. Среди просто неопределенных ссылок на функции, объявленные в заголовке, но не реализованные, я получил много этих ошибок typeinfo.

Решением было перезапустить систему сборки, чтобы скомпилировать и связать новый файл cpp.

2 голосов
/ 26 августа 2016

У меня такая же ошибка, когда моему интерфейсу (со всеми чисто виртуальными функциями) требовалась еще одна функция, и я забыл обнулить ее.

у меня было

class ICommProvider { public: /** * @brief If connection is established, it sends the message into the server. * @param[in] msg - message to be send * @return 0 if success, error otherwise */ virtual int vaSend(const std::string &msg) = 0; /** * @brief If connection is established, it is waiting will server response back. * @param[out] msg is the message received from server * @return 0 if success, error otherwise */ virtual int vaReceive(std::string &msg) = 0; virtual int vaSendRaw(const char *buff, int bufflen) = 0; virtual int vaReceiveRaw(char *buff, int bufflen) = 0; /** * @bief Closes current connection (if needed) after serving * @return 0 if success, error otherwise */ virtual int vaClose(); };

Последний vaClose не является виртуальным, поэтому скомпилированный не знал, где получить реализацию для него, и поэтому запутался. мое сообщение было:

... TCPClient.o :(. Rodata + 0x38): неопределенная ссылка на `typeinfo для ICommProvider '

Простое изменение с

virtual int vaClose();

до

virtual int vaClose() = 0;

исправил проблему. надеюсь, это поможет

2 голосов
/ 31 марта 2016

в моем случае я использовал стороннюю библиотеку с заголовочными файлами и другими файлами. я переклассифицировал один класс, и ошибка ссылки, как это произошло, когда я пытаюсь создать экземпляр своего подкласса.

как упомянул @sergiy, зная, что это может быть проблемой 'rtti', мне удалось обойти ее, поместил реализацию конструктора в отдельный файл .cpp и применил флаги компиляции -fno-rtti файл . это хорошо работает.

, поскольку я до сих пор не совсем понимаю внутреннюю ошибку этой ссылки, я не уверен, является ли мое решение общим. однако, я думаю, что стоит попробовать, прежде чем пытаться использовать адаптер, как упомянуто @francois. и, конечно, если доступны все исходные коды (не в моем случае), лучше перекомпилируйте с помощью '-frtti', если это возможно.

еще одна вещь, если вы решите попробовать мое решение, попробуйте сделать отдельный файл как можно более простым и не использовать некоторые изящные функции C ++. уделять особое внимание вещам, связанным с повышением, потому что многое зависит от rtti.

1 голос
/ 10 октября 2018

В моем случае это просто проблема зависимости библиотеки, даже если у меня есть вызов dynamic_cast После добавления достаточного количества зависимостей в make-файл эта проблема исчезла.

1 голос
/ 19 марта 2016

Я сталкиваюсь с редкой ситуацией, но это может помочь другим друзьям в подобной ситуации. Я должен работать на старой системе с gcc 4.4.7. Я должен скомпилировать код с поддержкой c ++ 11 или выше, поэтому я собираю последнюю версию gcc 5.3.0. При сборке моего кода и создании ссылок на зависимости, если зависимость создается с помощью более старого компилятора, я получил ошибку «неопределенная ссылка на», хотя я четко определил путь ссылки с помощью -L / path / to / lib -llibname. Некоторые пакеты, такие как boost и проекты, собранные с помощью cmake, обычно имеют тенденцию использовать более старый компилятор, и они обычно вызывают такие проблемы. Вы должны пройти долгий путь, чтобы убедиться, что они используют более новый компилятор.

0 голосов
/ 18 сентября 2018

Убедитесь, что ваши зависимости были скомпилированы без -f-nortti.

Для некоторых проектов вы должны установить его явно, как в RocksDB:

USE_RTTI=1 make shared_lib -j4
...