对“__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
的未定义引用
到底是怎么回事?
With gcc 4.6 when trying to execute this code:
#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;
}
I'm getting the following error:
1. undefined reference to __gxx_personality_sj
2. undefined reference to _Unwind_SjLj_Register
3. undefined reference to _Unwind_SjLj_Unregister
4. undefined reference to _Unwind_SjLj_Resume
What on hell is going on?!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
这些函数是 GCC 的 C++ 异常处理支持的一部分。 GCC 支持两种异常处理,一种基于对 setjmp 和 longjmp 的调用(sjlj 异常处理),另一种基于 DWARF 调试信息格式(DW2 异常处理)。
如果您尝试在单个可执行文件中混合使用不同异常处理实现编译的对象,则会发生此类链接器错误。您似乎正在使用 DW2 GCC,但您尝试使用的某些库是使用 sjlj 版本的 GCC 编译的,从而导致这些错误。
简而言之,此类问题是由不同编译器之间的 ABI 不兼容引起的,当您混合使用不同编译器编译的库或使用同一编译器的不兼容版本时,就会发生此类问题。
These functions are part of the C++ exception handling support for GCC. GCC supports two kinds of exception handling, one which is based on calls to setjmp and longjmp (sjlj exception handling), and another which is based on the DWARF debugging info format (DW2 exception handling).
These sorts of linker errors will occur is you try to mix objects that were compiled with different exception handling implementations in a single executable. It appears that you are using a DW2 GCC, but some library that you are attempting to use was compiled with a sjlj version of GCC, leading to these errors.
The short answer is that these sorts of problems are caused by ABI incompatibilities between different compilers, and so occur when you mix libraries compiled with different compilers, or use incompatible versions of the same compiler.
正如smallB 在评论中指出的,您可能使用过
gcc
,专注于C
程序,但您有一个C++
程序。要编译
C++
程序,请确保使用g++
编译器驱动程序!示例:
不好:
gcc -o foo.exe foo.cpp
好:
g++
-o foo.exe foo.cpp
as smallB noted in a comment, you may have used
gcc
, focused onC
programs, but you had aC++
program.To compile a
C++
program, make sure to use theg++
compiler driver instead!example:
BAD:
gcc -o foo.exe foo.cpp
GOOD:
g++
-o foo.exe foo.cpp
以防万一其他人遇到这个问题:我在为我的项目创建
.o
文件后更改了编译器。当我重建同一个项目时,新编译器没有构建新的
.o
文件,因此它们丢失了一些关键信息。删除旧文件并重建后,错误已修复。我认为从头开始重建,不删除,会起到同样的作用。
Just in case anyone else has this problem: I changed compilers AFTER creating
.o
files for my project.When I rebuilt the same project, the new compiler didn't build new
.o
files, so they were missing some key info. After deleting the old files and rebuilding, the error was fixed.I assume rebuilding from scratch, without the delete, would work the same.
gcc 命令只是一个驱动程序,它为您提供的源文件运行正确的编译器(或者如果您提供目标文件则运行链接器)。对于具有已知文件扩展名的 C++ 源文件,它将运行 C++ 编译器(对于 GCC,称为 cc1plus)并正确编译代码。
但是它不会自动链接到 C++ 标准库(对于 GCC 来说称为
libstdc++
)。要解决此问题,您需要通过在链接时将
-lstdc++
添加到选项中来显式链接到该库,或者仅使用g++
驱动程序进行编译和链接,这自动将-lstdc++
添加到链接器选项中。因此,您可以使用 gcc 来编译 C++ 程序,但是如果您使用标准库或 C++ 运行时的任何功能(包括异常处理),那么您需要使用 -lstdc++ 链接到 C++ 运行时 (或
-lsupc++
仅适用于运行时)。使用g++
会自动为您完成此操作。这在手册中有记录: https://gcc.gnu.org/onlinedocs/ gcc/调用-G_002b_002b.html
The
gcc
command is just a driver program that runs the right compiler for the source file you give it, (or run the linker if you give it object files). For a C++ source file with a known file extension it will run the C++ compiler (which for GCC is calledcc1plus
) and compile the code correctly.But it won't automatically link to the C++ Standard Library (which for GCC is called
libstdc++
).To solve the problem you either need to link to that library explicitly by adding
-lstdc++
to the options when linking, or alternatively just compile and link with theg++
driver instead, which automatically adds-lstdc++
to the linker options.So you can use
gcc
to compile C++ programs, but if you use any features of the standard library or C++ runtime (including exception handling) then you need to link to the C++ runtime with-lstdc++
(or-lsupc++
for just the runtime). Usingg++
does that for you automatically.This is documented in the manual: https://gcc.gnu.org/onlinedocs/gcc/Invoking-G_002b_002b.html
使用 minGW-g++.exe 而不是 gcc.exe
看看现在会发生什么。
Use minGW-g++.exe not gcc.exe
See what happens now.