このC++プログラムはCGIスクリプトであり、例外を処理する必要はありません。プロセスが終了した後、パフォーマンスをわずかに向上させ、OS(Linux)にクリーンアップを処理させたいと思います。
私は標準C++ライブラリを使用しており、Perlのようにdie
に任意の関数を必要とします:例外がスローされるときはいつでも。 巻き戻しせずに、または私のプロセスでさらにコードを実行します。
-fno-exceptionsはどのように機能しますか?コードにまったく問題がなく、基本的に例外のようなふりをする場合は、存在しません。しかし、私はする std :: c ++ライブラリを使用しますできる throw()?
オプション#1:例外をキャッチしない。
例外は、スローまたはキャッチされない限り、それほどオーバーヘッドがありません。投げてキャッチする準備ができていない場合は、とにかく死ぬつもりなので、その時点でのパフォーマンスへの影響は軽微です。例外が処理されない場合、スタックの巻き戻しは実行されないことにも注意してください。プログラムは、スタックの巻き戻しを実行せずに単に終了します。
G ++では、実際にスローされない例外にはオーバーヘッドがほとんどないことに注意することが重要です。 G ++は、スタックを介したプログラムの実行を追跡するのに十分な追加情報、およびデストラクタを呼び出すための追加コードなどを生成します。ただし、例外が実際にスローされるまで、この追加コードやデータは使用されません。したがって、例外は有効になっているが使用されていないコードと、例外が無効になっているコード(メカニズムを問わず)のパフォーマンスに違いはありません。
オプション#2:_-fno-exceptions
_を渡します。
このフラグはG ++に 2つのことを行う を指示します。
abort()
呼び出しに置き換えられます-fno-exceptions
_コードを介してアンワインドしようとすると、アンワインドデータがないため、その時点で中止されます。これにより、必要に応じて、すべての例外をabort()
sに効果的に変換できます。ただし、throw
は許可されないことに注意してください。コードに実際のthrow
sまたはcatch
sを指定すると、コンパイル時エラーが発生します。
オプション#3:(移植不可、非推奨!)__cxa_allocate_exceptionをフックします。
C++例外は、(特に)__cxa_allocate_exceptionおよび__cxa_throw内部ライブラリ関数を使用して実装されます。これらの関数をabort()にフックするLD_PRELOADライブラリを実装できます。
_void __cxa_allocate_exception() { abort(); }
void __cxa_throw() { abort(); }
_
警告:これは恐ろしいハックです。 x86およびx86-64で動作するはずですが、これはお勧めしません。特に、_-fno-exceptions
_のように、実際にパフォーマンスが向上したり、コード領域が節約されたりすることはありません。ただし、throw
sをabort()
sに変換しながら、throw
構文を許可します。
_-fno-exceptions
_は、すべての標準ライブラリスローをstd::abort()
への呼び出しに変換します。これは直接変更できない部分を処理し、残りはコードでそれらをまったく使用しないことです。
もちろん、私はあなたがこれをすることの正当化を本当に疑います。実際にスローしたときにパフォーマンスが「失われる」だけであり、言語の重要で役立つビットを捨てています。
誰かがこの質問に遭遇した場合に備えて、@ GManNickGおよび( https://stackoverflow.com/a/7249460/157344 )および@bdonlan( https: //stackoverflow.com/a/7249442/157344 )が回答で述べています。残念ながら、すべての例外処理コードを削除してすべてのスローをアボートに変換する「-fno-exception」に関する部分は間違っています。まあ-部分的に間違っています。これは、このフラグを使用して問題のライブラリ(libstdc ++ v3)をコンパイルする場合に当てはまりますが、このフラグを使用してコンパイルする独自のコードでこのライブラリを(.aまたは.soまたは.dllなどとして)使用する場合は当てはまりません。 。後者の場合、あなたのコードの例外処理コードは禁止されていますが、ライブラリ内の例外処理へのすべての呼び出しは残ります(ライブラリがコンパイルされたため[〜#〜]なし[〜#〜 ]このフラグ、例外は有効になっているため)new
を使用すると、実行可能ファイル[〜#〜] [〜#〜 ]には例外処理コードがあります-唯一の違いは、catch()
(コードで禁止されています)ではこれらの例外について何もできないため、すべてのスローが事実上終了することですabort()
と同じですが、誰もそれをキャッチできないからです。
見積もり:
このC++プログラムはCGIスクリプトです。例外を処理する必要はありません。
しかし、私はあなたがそうすることをお勧めします。そうすることは、あなたが間違っている可能性があることを考えていることを意味します。
あなたのコードのどこにもそれらを捕まえないでください。その場合、終了ハンドラが呼び出され、プログラムが「クラッシュ」します。