インクリメント
出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2024/03/17 22:38 UTC 版)
真理値とインクリメント
アセンブリ言語(アセンブラ)や初期のプログラミング言語は、真理値を表す専用のデータ型(ブーリアン型)を持たず、整数型で代用することが多かった。整数で代用する場合、通例0を偽 (false) として扱い、また0以外をすべて真 (true) として扱う。C言語はこの仕様を引きずっており、論理演算の結果は基本整数型int
となる。これはANSI C(C89)以前だけでなく、組み込みのブーリアン型_Bool
が追加されたC99以降も変わらない。
このようにブーリアン型として整数型を使用すると、本来インクリメントで記述する必要がない(インクリメントで記述してはいけない)コードにも、誤って使われてしまうことがある。例えば真理値を表すフラグ変数の値を偽から真に変更する場合、通常は変数に何らかの固定値(一般的な代表値としては1)を代入する。しかし、整数型では0をインクリメントすると1になることから、代入ではなくインクリメントでも偽から真に変更することができてしまう。
ソフトウェア工学や安全工学の未発達な時代に、不適切なインクリメント命令の使用が致命的なバグを生み、重篤な事故を引き起こした事例として、放射線療法機器のセラック25が挙げられる。セラック25は1985年から1987年にかけて知られる限り6つの重大な被曝事故を引き起こし、少なくとも5人の患者を死亡させた。事故原因には複数の要因があるが、まずセラック25は従来機に搭載されていた電気機械式の安全保護装置(ハードウェア・インターロック)を取り除き、(当時はハードウェア制御よりも安全だと思われていた)ソフトウェア制御に置き換えてしまっていた。装置を制御するコンピュータPDP-11のオペレーティングシステム[注釈 3]において、安全性を確保するためのソフトウェア・インターロックのひとつに使われていた、Class3と呼ばれるフラグ変数は、値が0以外の場合、装置に何らかの不一致があり、放射線治療を続行できないことを意味するものだった。セットアップテストのルーチンを通過するたびにClass3変数の値がインクリメントされるコードになっていたが、このClass3変数は1バイト(1オクテット)であり、十進数で0から255までの数値しか表現できない。値が255のときにインクリメントしてしまうと、オーバーフローが発生して0に戻ってしまう。この異常動作はセットアップテストを256回通過するたびに発生する。つまり、本来はフラグが真でなければならない場面で偽となり、障害が正しく検出されないというバグが存在していた[14]。これにより、装置の安全チェックがバイパスされてしまい、患者に過度の放射線が照射され、患者が死亡する可能性があった。当初セラック25のメーカーはこのバグに気づかず、「事故は起こりえない」と回答したことが被害を拡大させた。
なお、Cとは異なり、C++には、ISO規格として標準化される前にリリースされた段階でbool
型が存在していた。C++98規格として標準化された時点で、このbool
型は値としてfalse
(0
) あるいはtrue
(1
) のみをとることが保証されるようになった(とはいえ、すべてのC++実装がこの規格で定められた仕様に正しく準拠していたわけではない)。また、bool
型の値をどれだけインクリメントしてもtrue
となるように定められていたが、bool
に対するインクリメントはC++98の時点で非推奨となっていた(この仕様決定にセラック25の教訓が反映されていたかどうかは定かではない)。その後、C++17で、インクリメント演算子「++
」がbool
型に適用できないように規定され、bool
型へのインクリメントは正式に削除された[15]。
JavaやC#のような後発の安全な言語では、ブーリアン型へのインクリメントは登場当初から禁止されている。
注釈
出典
- ^ a b “インクリメント (++) - JavaScript”. MDN Web Docs. 2021年5月18日閲覧。
- ^ a b “デクリメント (--) - JavaScript”. MDN Web Docs. 2021年5月18日閲覧。
- ^ EXP30-C. 副作用が発生する式の評価順序に依存しない
- ^ System.Inc - RAD Studio API Documentation
- ^ System.Dec - RAD Studio API Documentation
- ^ Inc / Reference for unit 'System' | Free Pascal
- ^ Dec / Reference for unit 'System' | Free Pascal
- ^ InterlockedIncrement function (winnt.h) - Win32 apps | Microsoft Learn
- ^ Interlocked.Increment Method (System.Threading) | Microsoft Learn
- ^ インクリメント/デクリメント演算子 (C) - cppreference.com
- ^ インクリメント/デクリメント演算子 (C++) - cppreference.com
- ^ Swift 3.0でなぜ「Cスタイルのforループ」「++/--演算子」などの仕様が廃止されたのか - Build Insider
- ^ IEC 62304 実践ガイドブック | 医療機器ソフトウェアに関する各国規制対応のための実例解説 | 一般社団法人 電子情報技術産業協会(JEITA)
- ^ An Investigation of the Therac-25 Accidents -- Part III, Internet Archive
- ^ 非推奨だった bool 型に対するインクリメント演算子を削除 - cpprefjp C++日本語リファレンス
- 1 インクリメントとは
- 2 インクリメントの概要
- 3 高水準言語での扱い
- 4 真理値とインクリメント
- 5 ネーミングでの使用
固有名詞の分類
- インクリメントのページへのリンク