未定義動作(UB) とは、C言語の標準が結果を定義していないプログラムの動作です。コンパイラやシステムは、目立たないエラーから完全なクラッシュやデータの損傷まで、あらゆる行動をとる可能性があります。
未定義動作の典型的な原因:
未定義動作を最小化する方法:
int arr[5]; arr[10] = 0; // UB — 配列の範囲外アクセス int* p = NULL; *p = 42; // UB — NULLポインタの逆参照
質問: 整数を0で割った場合、プログラムはどうなるか?
答え: C標準(ISO C99 6.5.5)では、0での除算は未定義動作です。クラッシュ、ゴミの発生、または「論理的に正しい」出力があるかもしれませんが、標準は結果を保証しません。
int a = 10, b = 0; printf("%d", a / b); // 未定義動作
歴史
組み込みシステムのプロジェクトの1つで、プログラマが配列の範囲を超えて1つの要素にアクセスするループを書きました。アプリケーションは正常に動作しましたが、1ヶ月後にメモリ内の他のデータが破損し始めました(短期的なエラーで、複製が難しい)。問題は、詳細なレビューと静的解析ツールによるチェックの後に発見されました。
歴史
開発者はNULLポインタの逆参照が常にクラッシュを引き起こすと考え、NULLチェックを追加しませんでした。しかし、珍しいプラットフォームでは、不正確(しかし致命的でない)なメモリの変更が発生し、他の構造が壊れ、追跡が難しいバグが引き起こされました。
歴史
擬似乱数生成に除算を利用し、引数のいくつかの値で0での除算が発生しました。ほとんどのプラットフォームではプログラムが単に「クラッシュ」しましたが、あるプラットフォームでは結果が不正確な数値となり、異なる環境間でバグの再現が不可能になりました。