未定义的引用`__gxx_personality_sj0`

sma*_*llB 21 c++ gcc linker-errors undefined-reference

使用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;
}
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:
1.未定义引用__gxx_personality_sj
2.未定义引用_Unwind_SjLj_Register
3. undefined引用_Unwind_SjLj_Unregister
4. undefined引用_Unwind_SjLj_Resume

到底是怎么回事?!

Man*_*rse 28

这些函数是GCC的C++异常处理支持的一部分.GCC支持两种异常处理,一种是基于对setjmp和longjmp(sjlj异常处理)的调用,另一种是基于DWARF调试信息格式(DW2异常处理).

如果您尝试在单个可执行文件中混合使用不同异常处理实现编译的对象,则会发生这些类型的链接器错误.您似乎正在使用DW2 GCC,但您尝试使用的某些库是使用sjlj版本的GCC编译的,从而导致这些错误.

简短的回答是,这些问题是由不同编译器之间的ABI不兼容引起的,因此当您混合使用不同编译器编译的库或使用相同编译器的不兼容版本时会出现这种情况.

  • 我修好了.我错误的是在工具链中作为编译器,我有i686-pc-mingw32-gcc-4.6.0.exe但作为链接器:mingw32-g ++.exe.我把它改成了i686-pc-mingw32-g ++.exe并且问题解决了.谢谢. (11认同)
  • @JonathanWakely请重读来自smallB的评论,它说gcc用作编译器,g ++用作链接器,根据你的解释,它应该已经链接了libstdc ++.smallB还提到在将g ++版本切换到i686版本之后,"问题就解决了". (3认同)
  • @smallB你应该接受这个答案,如果它解决了你的问题! (2认同)
  • 虽然这个答案不适用于原始问题,但它可以帮助那些在这里遇到同样错误的人.在我的例子中,我在ubuntu 14上构建了一个归档库,并尝试在Windows上链接到它,运行mingw-w64编译器的seh版本.在Windows上安装mingw-64时,您可以选择下载seh或sjlj版本.但是当你使用apt-get在Ubuntu上安装它时,你会获得apt存储库中的版本.Ubuntu 14配置了sjlj版本,Ubuntu 16配置了seh版本. (2认同)

n61*_*007 8

正如smallB 在评论中指出的那样,你可能已经使用过gcc,专注于C程序,但你有一个C++程序.

要编译C++程序,请确保使用g++编译器驱动程序!

例:

坏: gcc -o foo.exe foo.cpp

好: g++-o foo.exe foo.cpp

  • 不太准确,`gcc`只是一个运行正确编译器的驱动程序,而对于`.cpp`或`.cc`文件,它将运行C++编译器.但与`g ++`驱动程序不同,它不会自动链接到C++标准库.当然,这在手册中有记录.https://gcc.gnu.org/onlinedocs/gcc/Invoking-G_002b_002b.html (2认同)

Ben*_*Ben 7

以防万一其他人有这个问题:我在.o为项目创建文件后更改了编译器.

当我重建同一个项目时,新编译器没有构建新.o文件,因此他们缺少一些关键信息.删除旧文件并重建后,错误已得到修复.

我假设从头开始重建,没有删除,将工作相同.

  • 这个答案被严重低估了,在疯狂搜索后修复了所有未定义的参考线。 (2认同)