0

たとえば、 throw() とマークされたメソッドがある場合

 void method() throw()
 {
      // do some stuff, call other functions
 }

それでも内部で例外発生すると、gcc はアプリケーションを終了します (「'xyz' のインスタンスをスローした後に終了します」というメッセージが表示されます)。

この動作を回避する方法はありますか?

たとえば、throw() を無視するか、eh_frame の生成を強制するコマンドライン スイッチです。等。

4

2 に答える 2

2

GCCマニュアルを試しましたか?

-fno-enforce-eh-specs

実行時に例外仕様の違反をチェックするコードを生成しないでください。このオプションは C++ 標準に違反しますが、` ' を定義するのと同じように、プロダクション ビルドでコード サイズを削減するのに役立つ場合がありますNDEBUG。これは、例外仕様に違反して例外をスローする許可をユーザー コードに与えるものではありません。コンパイラは引き続き仕様に基づいて最適化するため、予期しない例外をスローすると、実行時に未定義の動作が発生します。

EH フレームの生成を強制するわけではありませんが、呼び出しを停止する必要があるstd::unexpected()ため、ケースに役立つ場合があります。

ドキュメントが言うように、「コンパイラはまだ仕様に基づいて最適化する」ため、たとえば、への呼び出しをmethod()キャッチ サイトにインライン化できる場合は役に立ちません。コンパイラは、キャッチが必要ないと想定しているためです。例外はスローされないため、例外がスローされてもキャッチされません。への呼び出しがmethod()キャッチ サイトにインライン化できない場合、例外は呼び出されずに終了method()std::unexpected()、スタックの上位でキャッチされる可能性があります。

編集:これは、次の場合でも呼び出さstd::terminate()-fno-enforce-eh-specsます:

void func() throw() { throw ""; }
void func2() { func(); }
int main() { try { func2(); } catch (...) { } }

コンパイラは、 への呼び出しがfunc2非スロー関数のみを呼び出していることを確認できるため、catchは決して必要とされず、最適化されなくなります。例外がスローされても、キャッチされません。

これ動作し-fno-enforce-eh-specs、終了しません:

/* func2.cc */
void func() throw();
void func2() { func(); }

/* main.cc */
void func2();
int main() { try { func2(); } catch (...) { } }

ここで、 をコンパイルするときmain.cc、コンパイラは がfunc2スローされるかどうかを判断できません。これは、 には例外指定がなく、その定義が に表示されないmain.ccため、catchを省略できないためです。例外がスローされると、キャッチされます。

于 2012-10-26T13:36:50.440 に答える
1

...を呼び出して独自の終了ハンドラを提供できますstd::set_terminateが、そこから戻ることは合法ではないと思うので、実際にできることは何らかの方法で終了することだけです。

独自の予期しない例外ハンドラーをstd::set_unexpected: デフォルトの呼び出しで提供できstd::terminateますが、別のことを行うこともできます (ログに記録して例外を飲み込むなど)。ただし、有効に回復できるかどうかは、プログラムによって異なります。また、非推奨とマークされているのを見たので、これに依存することはおそらく最善のアイデアではありません.

于 2012-10-26T12:32:15.403 に答える