Неопределенная ссылка на `__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 Посмотрите, что теперь происходит.