22

このコードを実行しようとするときのgcc4.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 は 2 種類の例外処理をサポートしています。1 つは setjmp および longjmp への呼び出しに基づくもの (sjlj 例外処理) で、もう 1 つは DWARF デバッグ情報形式に基づくもの (DW2 例外処理) です。

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

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

于 2011-10-13T09:04:20.663 に答える
9

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

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

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

于 2012-11-08T05:51:52.357 に答える
3

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

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

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

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

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

于 2015-06-04T14:20:30.413 に答える