23

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?!

smallB
  • 16,662
  • 33
  • 107
  • 151

5 Answers5

31

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.

Mankarse
  • 39,818
  • 11
  • 97
  • 141
  • 11
    I fixed that. What I've had wrong was in toolchain as a compiler I've had i686-pc-mingw32-gcc-4.6.0.exe but as a linker: mingw32-g++.exe. I've change it to i686-pc-mingw32-g++.exe and problem is solved. Thanks. – smallB Oct 13 '11 at 09:06
  • @Alex, except this answer doesn't solve the problem. The OP's error was caused by not linking to libstdc++ at all, not by linking to an incompatible one. – Jonathan Wakely Jun 04 '15 at 14:13
  • 3
    @JonathanWakely please reread the comment from smallB, it says gcc was used as a compiler and g++ was used as a linker, which should have already linked libstdc++ according to your explanation. smallB also mentions that after switching g++ version to the i686 version the "problem is solved". – Alex Jun 04 '15 at 15:39
  • Nice answer, fixed my problem. I was using the mingw-g++ installed by CodeBlocks instead of the one I had installed :D – Javid May 20 '16 at 17:05
  • 2
    Though this answer is not for the original question, it helps people who landed here with the same error. In my case, I built an archive lib on ubuntu 14 and tried to link to it on Windows, running the seh version of the mingw-w64 compiler. When installing mingw-64 on windows you can choose to download either the seh or sjlj version. But when you use apt-get to install it on Ubuntu you get the version that is in the apt repository. Ubuntu 14 is configured with the sjlj version and Ubuntu 16 has the seh version. – nmgeek Aug 06 '17 at 01:10
12

as smallB noted in a comment, you may have used gcc, focused on C programs, but you had a C++ program.

To compile a C++ program, make sure to use the g++ compiler driver instead!

example:

BAD: gcc -o foo.exe foo.cpp

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

Community
  • 1
  • 1
n611x007
  • 8,952
  • 8
  • 59
  • 102
  • 2
    Not quite accurate, `gcc` is just a driver progam that runs the correct compiler, and for a `.cpp` or `.cc` file it will run the C++ compiler. But unlike the `g++` driver it doesn't automatically link to the C++ Standard Library. This is documented in the manual, of course. https://gcc.gnu.org/onlinedocs/gcc/Invoking-G_002b_002b.html – Jonathan Wakely Jun 04 '15 at 14:14
  • @JonathanWakely most informative I love your comment! Kind touch to lighten a `C` kiddie like me. I've update my answer with intent to make it more accurate. I've kept it simple on purpose, too. As per trivia, there are approx. 288715 words in the docs - obviously! ;) – n611x007 Jun 04 '15 at 16:42
9

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.

Ben
  • 54,723
  • 49
  • 178
  • 224
3

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 called cc1plus) 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 the g++ 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). Using g++ does that for you automatically.

This is documented in the manual: https://gcc.gnu.org/onlinedocs/gcc/Invoking-G_002b_002b.html

Jonathan Wakely
  • 166,810
  • 27
  • 341
  • 521
  • 1
    Yep this solved it. Wasn't a problem between "mismatched SLJL and DWARF" at all, it was just linking a c program against some c++ libraries, so adding -lstdc++ fixed it). Thanks! also make sure it goes "after" the other libs that need it, and make sure the exact command that is being run contains it :) – rogerdpack Feb 23 '18 at 21:38
0

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