提问人:smallB 提问时间:10/13/2011 最后编辑:Богуслав ПавлишинецьsmallB 更新时间:2/13/2020 访问量:41241
未定义对“__gxx_personality_sj0”的引用
undefined reference to `__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.未定义对 2 的
引用。未定义对 3 的
引用。未定义对 4 的
引用。未定义对__gxx_personality_sj
_Unwind_SjLj_Register
_Unwind_SjLj_Unregister
_Unwind_SjLj_Resume
这到底是怎么回事?!
答:
这些函数是 GCC 的 C++ 异常处理支持的一部分。GCC 支持两种异常处理,一种基于对 setjmp 和 longjmp 的调用(sjlj 异常处理),另一种基于 DWARF 调试信息格式(DW2 异常处理)。
当您尝试在单个可执行文件中混合使用不同的异常处理实现编译的对象时,就会发生这些类型的链接器错误。您似乎正在使用 DW2 GCC,但您尝试使用的某些库是使用 sjlj 版本的 GCC 编译的,从而导致这些错误。
简短的回答是,这类问题是由不同编译器之间的 ABI 不兼容引起的,因此,当您混合使用不同编译器编译的库或使用同一编译器的不兼容版本时,就会发生这种情况。
评论
以防万一其他人有这个问题:我在为我的项目创建文件后更改了编译器。.o
当我重新构建同一个项目时,新的编译器没有构建新文件,因此它们缺少一些关键信息。删除旧文件并重建后,错误已修复。.o
我认为从头开始重建,没有删除,工作方式是一样的。
评论
正如 smallB 在评论中指出的那样,您可能使用了 ,专注于程序,但您有一个程序。gcc
C
C++
要编译程序,请确保改用编译器驱动程序!C++
g++
例:
坏:gcc -o foo.exe foo.cpp
好: g++
-o foo.exe foo.cpp
评论
gcc
.cpp
.cc
g++
C
该命令只是一个驱动程序,它为您提供的源文件运行正确的编译器(或者,如果您为其提供目标文件,则运行链接器)。对于具有已知文件扩展名的 C++ 源文件,它将运行 C++ 编译器(对于 GCC 称为 )并正确编译代码。gcc
cc1plus
但它不会自动链接到 C++ 标准库(GCC 称为 )。libstdc++
若要解决此问题,需要通过在链接时添加到选项来显式链接到该库,或者只是编译并使用驱动程序进行链接,这会自动添加到链接器选项中。-lstdc++
g++
-lstdc++
因此,您可以使用来编译 C++ 程序,但是如果您使用标准库或 C++ 运行时的任何功能(包括异常处理),则需要使用 (或仅用于运行时) 链接到 C++ 运行时。使用会自动为您执行此操作。gcc
-lstdc++
-lsupc++
g++
这记录在手册中:https://gcc.gnu.org/onlinedocs/gcc/Invoking-G_002b_002b.html
评论
使用 minGW-g++.exe 而不是 gcc.exe 看看现在会发生什么。
评论
#include <limits>