今日、後輩と色々試していて面白いことに気付いた。Fortranのキーワードは、予約語ではない。Fortranはdo
とかif
とかといったキーワードを持っているが、これらは予約語ではない。
ググると規格書のセクション番号込で情報が出てくる。
ISO Fortran90 standard § 2.5.2 "Keyword"では、以下のような記述がある。
These keywords are not reserved words; that is, names with the same spellings are allowed.
「これらのキーワードは予約語ではない。つまり、同じ綴りの名前は許される」らしい。
規格書のドラフトはここで見ることができる。
質問している人もいるが、「キーワードを変数名として使うのはバッドプラクティスだ」という(当たり前の)答えが返ってきている。
どういうことかというと、以下のコードが合法だということだ。
program main integer :: do, end=0 do do=1, 10 end = end + do end do write(*,*) end end program main
ついでに、以下のようなコードも合法である。
program main logical::if=.true. if (if) if = then() write(*,*) if contains function then() logical then then = .true. end function then end program main
こんなコードが出てきた日には発狂すること請け合いであるが、Fortranコードのメンテをさせられて発狂寸前の人はこのような爆弾をコードに仕込んでみても面白いのかも知れない。
if
を関数にすることもできて、以下のコードはok
を出力する。
program main if(if(if(if(.true.)))) write(*, *) 'ok' contains function if(x) logical::x logical::if if = x end function if end program main
何一つokなところがない。
これだとif
関数が何もしていないからまだいいが、もっと悪意の強い関数にもできる。
program main if(if(.true.)) then write(*, *) 'ok' else write(*, *) 'not ok' end if contains function if(x) logical::x logical::if if = .not. x end function if end program main
このコードはnot ok
を出力する。確かにnot ok
だ。if
関数が定義されているばかりか、その関数がlogical
な値を受け取ってそれを反転するので。
ちなみにgfortran-5.5.0
で-Wall
と-Wextra
つきでコンパイルしても、上記のコードに警告は出ない(規格上予約語ではないとしても、警告くらいは出していいと思うのだが)。というわけで静かに爆弾を仕込むことができるので、使ってみてはいかがだろうか。