未定義動作
CおよびC++の標準には、全体を通していくつかの未定義の動作が定められており、これによってコンパイラの実装とコンパイル時検証の自由度が増す一方、これらの未定義動作がプログラムに含まれていた場合、実行時に未定義なふるまいをすることになる。特に、C言語のISO規格には、未定義動作の一般的な要因をリストしたアペンディクスが存在する。さらに、コンパイラは未定義動作に依存したコードを検出する必要はないため、多くのプログラマーは(経験豊富なプログラマーであっても)、誤って、あるいは単に数百ページに及ぶ可能性のある言語仕様に精通していないという理由で、未定義動作に依存したコードを書いてしまうのが一般的である。これにより、異なるコンパイラまたは異なる設定が使用されたときに明らかになるバグが発生する可能性がある。
状況によっては、未定義動作の実装に特定の制限がある場合がある。たとえば、CPUの命令セットの仕様では、一部の命令形式の動作が未定義とされる場合があるが、CPUがメモリ保護をサポートしている場合、仕様には、ユーザーがアクセスできる命令がオペレーティングシステムのセキュリティに穴を開けてはいけないと規定する上位のルールが含まれている可能性がある。したがって、実際のCPUはそのような未定義の命令に応答してユーザーレジスタを破損することは許されるが、たとえば、スーパーバイザーモードに切り替えることは許可されない。
ツールチェーンまたはランタイムによって、ソースコード中の特定の未定義動作のコードが実行時に使用可能な特定のメカニズムに対応付けされると明示的に文書化することにより、ランタイムプラットフォームは未定義動作に対してある種の制約または保証を行うこともできる。たとえば、言語仕様では定義されていない操作の特定の動作について、その言語のインタプリタは文書化することしないことも可能である。未定義動作のコードに対して、コンパイラはABIの実行可能コードを生成し、その動作に対する制限を行うことができる。すなわち、コンパイラのバージョンに依存する方法で言語仕様のセマンティクスのギャップを埋めることが可能である。これらの実装の詳細に依存することでソフトウェアの移植性は失われてしまうが、そのソフトウェアが特定のランタイム以外で使用することが想定されない場合など、このような移植性が問題ではない場合もある。
未定義動作は、プログラムのクラッシュなどのほか、データのサイレントロスや誤った結果の生成など、検出することが難しく一見正常に動作しているように見える障害を引き起こす可能性がある。