Подтвердить что ты не робот

Undefined ссылка на `__gxx_personality_sj0

С 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. undefined ссылка на __gxx_personality_sj0
2. undefined reference to
_Unwind_SjLj_Register '
3. undefined ссылка на _Unwind_SjLj_Unregister'
4. undefined reference to
_Unwind_SjLj_Resume '

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

4b9b3361

Ответ 1

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

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

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

Ответ 2

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

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

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

Ответ 3

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

Чтобы скомпилировать программу C++, обязательно используйте вместо этого драйвер компилятора g++!

Пример:

BAD: gcc -o foo.exe foo.cpp

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

Ответ 4

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

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

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

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

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