言語仕様と宇宙開発にまつわるエピソード
出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2021/08/26 08:19 UTC 版)
「FORTRAN 77の言語仕様」の記事における「言語仕様と宇宙開発にまつわるエピソード」の解説
FORTRANの「空白は無視する」という言語仕様が招く、コンマとピリオドの打ち間違いがコンパイルエラーにならず、間違ったプログラムになる、という例を説明する。 Cで、次のように書くプログラムの一部があったとする。 int i; (中略) for( i=1; i<=5; i++ ) { 何らかの処理; } これをFORTRAN66で書くと次のように書ける。 DO 10 I=1,5 何らかの処理 10 CONTINUE 最初の行は、整数型変数Iを1から5まで1ずつ増加させつつ、行ラベル10の行までを繰り返し実行することを表す。行ラベル10のCONTINUE文はループ制御の端末文ではなく、どこにでも置ける「何もしない」機能の文である。 この、DO文のコンマをピリオドに打ち間違えたとする。すると、空白を無視するFORTRAN66では、この行は、 DO10I=1.5 という、「DO10Iという実数型変数に1.5という実数を代入する代入文」と解釈される。FORTRANでは変数宣言が無い場合、DO10Iは実数型変数を暗黙に示すからである。この結果、このプログラムは(他のどこからも参照されない)変数DO10Iへの代入とただ1回の「何らかの処理」が実行されるだけとなり、意図した繰り返し処理は起こらない。 C言語などでは、空白文字は字句要素の切れ目として解釈されるため、DO と 10 と Iが結合して一つの字句要素になることはない。 「これが原因でNASAの宇宙ロケットが制御不能になり爆破された」という話が度々語られる。しかしこの話は、1960年代前半のほぼ同時期にあった、二つの異なった事件の混同による、ある種の「都市伝説」である。 要約すると、 FORTRANの言語仕様が原因で生じたバグは、実機ではなくソフトウェアだけでの実行結果の異常として発覚し修正されたため、実際のロケット打ち上げには関係していない。これはマーキュリー計画において起きた。 宇宙機のロストにつながったプログラムのミスは言語仕様とは関係なく、プログラムするべき、として示された数式において、必要な線が欠けていたため発生した。これはマリナー1号において起きた。プログラミング(コーディング)に間違いは無くても、要求された仕様の時点でその中にバグがあるかもしれない、という教訓となっている。 DO文によるバグは、1963年、マーキュリー宇宙船の軌道計算ソフトウェアを開発中に、スタッフの一人が計算精度に問題があることに気づいた。コードを調査した結果、「DO 10 I=1.10」という行を発見した。それが原因で、ループにより近似の精度を高めるはずのコードが、ループしないため精度を高めることなく通り過ぎてしまっていた。これを「DO 10 I=1,10」と修正したところ、期待した精度が得られるようになった。 宇宙機の喪失につながった事故は、1962年、金星探査機マリナー1号を打ち上げるアトラスロケットには、Rate SystemおよびTrack Systemと呼ばれる二種類の制御系統が搭載されていた。Rate Systemは搭載型であり、地上型のTrack Systemは前者に対するバックアップとして動作する。1962年7月、マリナー1号の打ち上げ直後に、ロケットのguidanceアンテナは必要な性能を発揮しなくなり、搭載型システムのみに頼ってロケットは制御されることになった。しかし搭載型システムには次のような仕様バグがあった。「このようにプログラムすべき」として指示されていた手書きの数式中の、平均化を示す線(しばしば「ハイフン」と言及されるが、正確にはオーバーライン)が欠落しており、そのため平均化した値を使うべきところでそのままの値が使われ、微妙なタイミング差の平滑化処理に問題があった(プログラム自体は「指示された仕様の通り」正しく書かれていた。指示された仕様が間違っていたのである)。結果として、制御コンピュータは、ロケットが正常に上昇しているにも関わらず、異常な補正動作をロケットに指示し続け、正常なコースから外れていった。結局、ロケットには破壊指令が送られ自爆し、マリナー1号は大西洋へと沈んだ。
※この「言語仕様と宇宙開発にまつわるエピソード」の解説は、「FORTRAN 77の言語仕様」の解説の一部です。
「言語仕様と宇宙開発にまつわるエピソード」を含む「FORTRAN 77の言語仕様」の記事については、「FORTRAN 77の言語仕様」の概要を参照ください。
- 言語仕様と宇宙開発にまつわるエピソードのページへのリンク