Неопределенная ссылка на `__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. неопределенная ссылка на __gxx_personality_sj
2. неопределенная ссылка на _Unwind_SjLj_Register
3. неопределенная ссылка на _Unwind_SjLj_Unregister
4. неопределенная ссылка на _Unwind_SjLj_Resume

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

4 ответа

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

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

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

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

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

пример:

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

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

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

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

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

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

Используйте minGW-g++. Exe, а не gcc.exe Посмотрите, что теперь происходит.

Другие вопросы по тегам