共有ライブラリからexeceptionをスローし、別のライブラリでそれをキャッチしています。私はすべてのソースコードを制御しているので、問題ないはずで、g++4.4.5を使用しています。まず、次のコードは機能しませんでした。
try
{
// do something that throws tags::out_of_range in the other shared lib
}
catch(const tags::out_of_range& e)
{
cout << "out_of_range " << typeid(tags::out_of_range()).name() << endl;
cout << "out of range exception " << typeid(e).name() << endl;
}
catch (const exception& e2)
{
cout << "out_of_range " << typeid(tags::out_of_range()).name() << endl;
cout << "other exception " << typeid(e2).name() << endl;
}
私はいつもstd::exceptionだけをキャッチすることになりました。コードに見られるようにtypeid()。name()を出力すると、考えられる説明が得られます。
out_of_range FN4tags12out_of_rangeEvE
その他の例外N4tags12out_of_rangeE
名前が一致していないことがわかります。正しく理解していれば、クラスが異なるモジュールにある場合、名前は実際には動的キャストと比較して文字列になります。
そこで、どこかで-fPICを追加して試してみると、名前を出力しても同じ結果が得られますが、突然機能しました(つまり、out_of_range例外が発生しました)。位置に依存しないコードはもはや重要ではないと思い、-fPICに関するg++のマニュアルページを調べました。
「このオプションは、m68k、PowerPC、SPARCに違いをもたらします」
そして、私はx86-64を使用しています。この場合、コードの配置がどのように違いを生むのか本当にわかりませんか?また、typeid名が文字列で比較されている場合、-fPICでも異なるため、std::exception句で終わると思いました。
では、質問:-fPICが違いを生むのはなぜですか?