неопределенная ссылка на `__gxx_personality_sj0` - PullRequest
21 голосов
/ 13 октября 2011

С gcc 4.6 при попытке выполнить этот код:

   #include <iostream>

using namespace std;

#include <bitset>

int main()
{
   //Int<> a;
   long long min = std::numeric_limits<int>::min();
   unsigned long long max = std::numeric_limits<int>::max();
   cout << "min: " << min << '\n';
   cout << "max: " << max << '\n';
   cout << (min <= max);
   std::bitset<64> minimal(min);
   cout << "minimal: " << minimal;

   return 0;
}

Я получаю следующую ошибку:
1. неопределенная ссылка на __gxx_personality_sj
2. неопределенная ссылка на _Unwind_SjLj_Register
3. неопределенная ссылка на _Unwind_SjLj_Unregister
4. неопределенная ссылка на _Unwind_SjLj_Resume

Что, черт возьми, происходит?!

Ответы [ 4 ]

29 голосов
/ 13 октября 2011

Эти функции являются частью поддержки обработки исключений в C ++ для GCC.GCC поддерживает два вида обработки исключений, один из которых основан на вызовах setjmp и longjmp (обработка исключений sjlj), а другой основан на формате информации отладки DWARF (обработка исключений DW2).

Эти видыОшибки компоновщика произойдут, если вы попытаетесь смешать объекты, которые были скомпилированы с различными реализациями обработки исключений, в один исполняемый файл.Похоже, что вы используете GCC DW2, но некоторая библиотека, которую вы пытаетесь использовать, была скомпилирована с версией GCC sjlj, что привело к этим ошибкам.

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

8 голосов
/ 10 августа 2014

как smallB отмечено в комментарии, вы, возможно, использовали gcc, ориентированные на C программы, но у вас была C++ программа.

Для компиляции *Программа 1008 *, убедитесь, что вы используете драйвер компилятора g++!

пример:

ПЛОХО: gcc -o foo.exe foo.cpp

ХОРОШО: g++-o foo.exe foo.cpp

7 голосов
/ 08 ноября 2012

На всякий случай, если у кого-то еще есть такая проблема: я изменил компиляторы ПОСЛЕ создания .o файлов для моего проекта.

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

Я предполагаю, что восстановление с нуля, без удаления, будет работать так же.

3 голосов
/ 04 июня 2015

Команда gcc - это просто программа драйвера, которая запускает правильный компилятор для исходного файла, который вы ему передаете (или запускаете компоновщик, если вы даете ему объектные файлы). Для исходного файла C ++ с известным расширением файла он запустит компилятор C ++ (который для GCC называется cc1plus) и правильно скомпилирует код.

Но не будет автоматически связываться со стандартной библиотекой C ++ (которая для GCC называется libstdc++).

Чтобы решить эту проблему, вам нужно либо явно связать эту библиотеку, добавив -lstdc++ к опциям при компоновке, либо альтернативно просто скомпилировать и связать с драйвером g++, который автоматически добавляет -lstdc++ к компоновщику варианты.

Таким образом, вы можете использовать gcc для компиляции программ на C ++, но если вы используете какие-либо функции стандартной библиотеки или среды выполнения C ++ (включая обработку исключений), вам необходимо связать среду выполнения C ++ с помощью -lstdc++ (или -lsupc++ только для времени выполнения). Использование g++ сделает это автоматически.

Это задокументировано в руководстве: https://gcc.gnu.org/onlinedocs/gcc/Invoking-G_002b_002b.html

...