Looking for c++ Answers? Try Ask4KnowledgeBase
Looking for c++ Keywords? Try Ask4Keywords

C++未定義の動作


前書き

未定義ビヘイビア(UB)とは何ですか? ISO C ++標準(§1.3.24、N4296)によれば、「この国際標準が要件を課さない動作」です。

これは、プログラムがUBに遭遇したときに、それが望むものを何でもすることが許されることを意味する。これはしばしばクラッシュを意味しますが、単に何もしない、 鬼の鼻を飛ばす 、または正しく動作するように見えるかもしれません!

言うまでもなく、UBを呼び出すコードを書くのは避けるべきです。

備考

プログラムに未定義のビヘイビアが含まれている場合、C ++標準ではビヘイビアに制約はありません。

  • 開発者が意図したとおりに動作するように見えるかもしれませんが、クラッシュしたり、奇妙な結果を生じる可能性があります。
  • 動作は、同じプログラムの実行間で異なる場合があります。
  • 定義されていない動作を含む行の前に来る行を含め、プログラムのどの部分も誤動作する可能性があります。
  • 実装では、未定義の動作の結果を文書化する必要はありません。

実装 、標準に従って未定義の動作を生成する動作の結果を記録することがありますが、そのような動作に依存するプログラムは移植性がありません。

未定義の動作が存在する理由

直感的には、未定義の振る舞いは、例外ハンドラのようなエラーをうまく扱うことができないため、悪いことです。

しかし、いくつかの動作を定義しないままにしておくことは、実際には、C ++の "あなたが使用していないものを支払わない"という約束の不可欠な部分です。未定義の動作により、コンパイラは開発者が自分が何をしているかを知り、上の例で強調表示されている誤りをチェックするためのコードを導入しないと想定することができます。

定義されていない動作の検出と回避

いくつかのツールを使用して、開発中に未定義の動作を発見することができます。

  • ほとんどのコンパイラでは、コンパイル時に未定義の動作が発生することを警告する警告フラグがあります。
  • gccとclangの新しいバージョンには、実行時にパフォーマンスコストで未定義の動作をチェックする、いわゆる "Undefined Behavior Sanitizer"フラグ( -fsanitize=undefined )が含まれています。
  • lintようなツールは、より完全な未定義の動作分析を実行することがあります。

定義されていない、指定されていない、 実装定義の振る舞い

C ++ 14標準(ISO / IEC 14882:2014)セクション1.9(プログラム実行)から:

  1. この国際標準の意味論的記述は、パラメータ化された非決定論的抽象機械を定義する。 [カット]

  2. 抽象マシンの特定の側面と操作は、この標準で実装定義 (例えばsizeof(int) )として記述されている。これらは抽象機械のパラメータを構成する 。各実装には、これらの点で特性と動作を記述したドキュメントが含まれていなければなりません。 [カット]

  3. 抽象機械のある種の他の局面および操作は、この規格では不特定のものとして記述されている(例えば、割り振り関数がメモリ割り当てに失敗した場合に新しい初期化子での式の評価)。可能であれば、この国際規格は一連の許容される行動を定義する。これらは抽象機械の非決定論的側面を定義する。したがって、抽象機械のインスタンスは、所与のプログラムおよび所与の入力に対して複数の可能な実行を有することができる。

  4. 特定の他の操作は、この規格では定義されていないと記述されています (または、例えば、 constオブジェクトを変更しようとする効果)。 [ :この規格は、未定義の動作を含むプログラムの動作には何も要求しない。 - 終了ノート ]

未定義の動作 関連する例