22

尝试执行此代码时使用 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

5 回答 5

30

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

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

简短的回答是,这类问题是由不同编译器之间的 ABI 不兼容引起的,当您混合使用不同编译器编译的库或使用同一编译器的不兼容版本时,就会发生此类问题。

于 2011-10-13T09:04:20.663 回答
11

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

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

例子:

坏的:gcc -o foo.exe foo.cpp

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

于 2014-08-09T22:59:08.687 回答
9

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

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

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

于 2012-11-08T05:51:52.357 回答
3

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

于 2015-06-04T14:20:30.413 回答
0

Use minGW-g++.exe not gcc.exe See what happens now.

于 2020-02-13T00:09:34.727 回答