未定義動作
コンピュータプログラミングにおいて、未定義動作(英: undefined behavior, UB)とは、コンピュータ言語が準拠する言語仕様において動作が予測できないと規定されたプログラムを実行した結果のことである。これに対して、言語仕様が動作結果を規定せず、プラットフォーム上の別のコンポーネントのドキュメント(ABIやトランスレータドキュメントなど)が処理系の実装を規定する動作のことを未規定動作(英: Unspecified behavior)と呼ぶ。
「未定義のコードを実行した結果コンパイラは何をしてもいい。鼻から悪魔が飛び出しても仕様に反しない」というcomp.std.cでの投稿から、C言語コミュニティではユーモアを込めて未定義動作のことを「鼻の悪魔(英: nasal demons)」と呼ぶことがある。
また、コンパイラはプログラマーに通知することなくソースコードに含まれる明示的なチェックを削除することができるため、例えば、未定義の動作が発生したかどうかをテストして検出する、などということは、定義上保証されない。これにより、可搬性のあるフェイルセーフオプションをプログラムすることは事実上困難、あるいは不可能となる(一部の構成では可搬性のない解決はできる)。
現在のコンパイラ開発では、通常、コンパイラのパフォーマンスを評価する際、マイクロ最適化を中心に実装されたベンチマーク結果によって比較する。これは、汎用デスクトップおよびラップトップ市場で主に使用されるプラットフォーム(amd64など)でも同様である。したがって、未定義動作を定めることにより、特定のソースコードの記述を実行時に任意のものにマッピングできるため、コンパイラのパフォーマンスを向上させるための十分な余地を与えることができる。
CやC++の場合、コンパイラはコンパイル時に未定義動作のチェックを行うことができるが、これは必須ではない。論理式におけるドントケア項(英: Don't-care term)と同じように、コンパイラの実装では未定義動作が含まれる場合には何をしても正しいと見なされる。未定義動作を引き起こさないコードを作成するのはプログラマーの責任だが、コンパイラの実装側で未定義動作が発生したかどうかの診断を実行することも可能であり、特に最近のコンパイラには、そのような診断を有効にするフラグがある。たとえば、-fsanitizeオプションを使用すると、 gcc 4.9およびclangで「未定義動作サニタイザー」(UBSan(英語版))を有効にすることができる。ただし、このフラグはデフォルトではなく、有効にするかどうかはコードをビルドする人に委ねられている。