web-dev-qa-db-ja.com

__builtin_trap:いつ使用するのですか?

gccは、「最適化のための」追加の組み込み関数を提供します。

それらの1つはvoid __builtin_trap (void)であり、これは基本的に、不正なコマンドを実行してプログラムを中止するためのものです。

ドキュメントから:

__builtin_trap関数は、プログラムを異常終了させます。 GCCは、ターゲットに依存するメカニズム(意図的に不正な命令を実行するなど)を使用するか、アボートを呼び出すことによって、この機能を実装します。使用されるメカニズムはリリースごとに異なる可能性があるため、特定の実装に依存しないでください。

exit(1)またはabortではなく、なぜこれを使用するのですか? gcc開発者がこれを最適化関数と見なしたのはなぜですか?

18
DevShark

exit(1)は、プログラムがエラーステータスコードで正常に終了するためです。 cppreferenceページ を参照してください。対照的に、__builtin_trapはプログラムを異常終了させます。

違いを確認する最も簡単な方法は、exitによって行われた保証を確認することです。これらのことの1つを実行したくない場合は、__builtin_trapの方が適しています。

デバッグは最も一般的な例です。__builtin_trapはデバッガーをトリガーしてプロセスをダンプできますが、exitはそうしません(プログラムがエラーで「正常に」終了するため)。

9
Guvante

__builtin関数は、必ずしも最適化のためのものではありません。「特別な命令」や「アーキテクチャー固有の操作」のサポートを含め、「コンパイラーがソースコードから直接実行できないことを行う」ためのものです。 __builtin関数の主な目的の1つは、後の段階でコンパイラがこれらの機能を「認識する」ことです。コンパイラーには「ライブラリーの最適化」がありますが、コンパイラーは__builtin関数をはるかに自由に使用して、動作が特定のものであることを判別できます。たとえば、__builtin_trapは、「継続しない次の命令」なので、コンパイラは次のようなコードについて心配する必要はありません。

if (x <= 0.0) __builtin_trap();
y = ln(x);

エラーは既にキャッチされているので、「lnの高速インラインバージョン」を利用できます。

また、__builtin_trapはデバッガーで「停止」として終了することがほぼ保証されていることにも注意してください。この場合、exit(1)などは、「不成功」の結果コードでプログラムを終了します。あなたがその数学エラーメッセージがどこから来たかを理解しようとしているなら...

4
Mats Petersson