web-dev-qa-db-ja.com

`__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への未定義の参照

一体何が起こっているのですか?

21
smallB

これらの関数は、GCCのC++例外処理サポートの一部です。 GCCは2種類の例外処理をサポートしています。1つはsetjmpおよびlongjmpへの呼び出しに基づくもの(sjlj例外処理)であり、もう1つはDWARFデバッグ情報形式(DW2例外処理)に基づくものです。

これらの種類のリンカエラーは、異なる例外処理実装でコンパイルされたオブジェクトを単一の実行可能ファイルに混在させようとすると発生します。 DW2 GCCを使用しているようですが、使用しようとしているライブラリの一部はGCCのsjljバージョンでコンパイルされているため、これらのエラーが発生します。

簡単に言えば、この種の問題は異なるコンパイラ間のABIの非互換性が原因で発生するため、異なるコンパイラでコンパイルされたライブラリを混在させたり、同じコンパイラの互換性のないバージョンを使用したりすると発生します。

28
Mankarse

smallB noted としてコメントで、gccを使用してCプログラムに焦点を当てた可能性がありますが、C++プログラムがありました。

C++プログラムをコンパイルするには、代わりにg++コンパイラドライバを使用してください。

例:

悪い例:gcc -o foo.exe foo.cpp

良い:g++-o foo.exe foo.cpp

10
n611x007

他の誰かがこの問題を抱えている場合に備えて、プロジェクト用に.oファイルを作成した後でコンパイラを変更しました。

同じプロジェクトを再構築したとき、新しいコンパイラは新しい.oファイルをビルドしなかったため、いくつかの重要な情報が欠落していました。古いファイルを削除して再構築した後、エラーが修正されました。

削除せずにゼロから再構築しても同じように機能すると思います。

7
Ben

gccコマンドは、指定したソースファイルに対して適切なコンパイラーを実行する(またはオブジェクトファイルを指定した場合はリンカーを実行する)ドライバープログラムです。既知のファイル拡張子を持つC++ソースファイルの場合、C++コンパイラ(GCCではcc1plusと呼ばれます)を実行し、コードを正しくコンパイルします。

しかしC++標準ライブラリ(GCCではlibstdc++と呼ばれます)に自動的にリンクしません。

この問題を解決するには、リンク時にオプションに-lstdc++を追加してそのライブラリに明示的にリンクするか、代わりにコンパイルしてg++ドライバーでリンクするだけで、自動的に-lstdc++が追加されます。リンカーオプションに。

したがって、gccを使用してC++プログラムをコンパイルできますが、標準ライブラリまたはC++ランタイム(例外処理を含む)の機能を使用する場合は、-lstdc++(または-lsupc++(ランタイムのみ)。 g++を使用すると、自動的に行われます。

これはマニュアルに記載されています: https://gcc.gnu.org/onlinedocs/gcc/Invoking-G_002b_002b.html

3
Jonathan Wakely

Gcc.exeではなくminGW-g ++。exeを使用してください。

0
Misha Taylor