脳を破壊するFortranコード

今日、後輩と色々試していて面白いことに気付いた。Fortranのキーワードは、予約語ではない。Fortrandoとかifとかといったキーワードを持っているが、これらは予約語ではない。

ググると規格書のセクション番号込で情報が出てくる。

Keywords in Fortran Wiki

ISO Fortran90 standard § 2.5.2 "Keyword"では、以下のような記述がある。

These keywords are not reserved words; that is, names with the same spellings are allowed.

「これらのキーワードは予約語ではない。つまり、同じ綴りの名前は許される」らしい。

規格書のドラフトはここで見ることができる。

https://wg5-fortran.org/

質問している人もいるが、「キーワードを変数名として使うのはバッドプラクティスだ」という(当たり前の)答えが返ってきている。

software.intel.com

どういうことかというと、以下のコードが合法だということだ。

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つきでコンパイルしても、上記のコードに警告は出ない(規格上予約語ではないとしても、警告くらいは出していいと思うのだが)。というわけで静かに爆弾を仕込むことができるので、使ってみてはいかがだろうか。