Cobolでピリオドを忘れると何が起きるのか
参考文献はこちら

- 作者: 西村恕彦,植村俊亮
- 出版社/メーカー: オーム社
- 発売日: 2012/01
- メディア: 単行本
- クリック: 1回
- この商品を含むブログ (1件) を見る
言語仕様の確認
まず、Cobolのif文は次のようになっている。
ここには説明が無いが、書き方2の場合はif文の後にピリオドを付けて「完結文」として、そこで文を終わらせることでif文が終わる。またこの規則だけを見ると、文が1個だけしか書けないように見えるが、実際にはdisplayなどをいくつ並べても「文」として扱われる。
注意書きがあるようにend-ifで終わらせるのが現代的な書き方である。またここでnext sentenceとするのは「if文の特別な書き方」であるが、やはり現代的な書き方であるcontinueとした場合は「continue文」という、文の一種で他でも使われる。
というわけで、こちら( http://www.kt.rim.or.jp/~kbk/zakkicho/15/zakkicho1506b.html#D20150615-3 )のリンク先にある「THEN、ELSE、 END-IFなどが省略可能」というのはほとんど変で、
- ELSE節を省略可能
- 昔は、END-IFではなくピリオドで終了するという記法だった
ということになる。
続いてピリオドが絡みそうなあたりの説明であるが、
ここで、「入れ子の場合にも欠陥がある」とあるが、どういうことかというと、ピリオドで「ネストしているifが全部終わる」という仕様のために、ネストの内側のifを終わってネストの外側のifに戻る、ということができない、ということである。
Cobolが世界で最初期に設計された高水準プログラミング言語のひとつであるということを考えれば、ifのネストといったようなことを考えていない仕様だったことは自然だろう。
実例
この「ピリオドで、ネストしたif文が全部終わる」という仕様により、「ピリオドを忘れると、コンパイルエラーにはならずにバグになってしまう」という例を示す。
こちら http://www.magata.net/memo/index.php?OpenCOBOL を参考にしたhello worldプログラムを改造した、次のようなサンプルを実行すると、
* Sample COBOL program identification division. program-id. sample. procedure division. if 0 is not zero then display "foo". display "bar" if 0 is zero then display "baz". display "hoge" stop run.
次のようになる。
$ cobc sample.cob $ cobcrun sample bar baz hoge
ここで、1個目のifに付いているピリオドを取ると、
* Sample COBOL program identification division. program-id. sample. procedure division. if 0 is not zero then display "foo" display "bar" if 0 is zero then display "baz". display "hoge" stop run.
$ cobc sample.cob $ cobcrun sample hoge
2個目のifまでの全体が、1個目のifのthen節の中に入ってしまって、「hoge」しかプリントされなくなる。なお、さらに2個目のピリオドが無くても「ifが終わっていない」というようなエラーにもならない。
そういったわけで「古いCobolでピリオドを忘れることの危険」については以上で述べた通りであるが、「ときどきの雑記帖」が気になるとしているように、字下げのルール化ではこのミスのチェックは難しいし(むしろC言語の if (); などで悪名高い「字下げに騙されるパターン」である。一応、ルール化により「意図が見かけで表現されるので、それが実際の動作と一致していない」と気付けるかもしれない、という可能性はある)、「ミサイル発射実験の失敗」というのもおそらく9割5分、マリナーとマーキュリーの2件の無関係な事故がたいてい混同されているFORTRANのそれの混同ではなかろうかと思う。