Fortranにはキーワードがいくつか存在します。if
とかdo
とかそういうやつです。これらはキーワードですが、予約語ではありません。
予約語かどうかで違いがあるのか、という話ですが、以下のコードが合法になります。
program main
integer :: do, end=0
do do=1, 10
end = end + do
end do
write(*,*) end
end program main
もちろん、if
も予約語ではないので、以下のコードも合法です。
program main
logical::if, then
if = .true.
then = .false.
if (if) if = then
write(*,*) if
end program main
変数名でなく関数名に使っても構わないので、if
という関数を定義して受け取ったlogical
の.not.
を取って返すようにすることもできます。
program main
if(if(.true.)) then
write(*, *) 'ok'
else
write(*, *) 'not ok'
end if
contains
logical function if(x)
logical::x
if = .not. x
end function if
end program main
このコードはnot ok
を出力します。もちろん、このようなコードは良くないからですね。
さて、これは本当に正しいコードなのでしょうか。コンパイラのバグではなくて?
Fortranには国際規格があり、そこでFortranの振る舞いが決められています。Fortranとして正しいコードかどうかは、コンパイラが決めるのではなく、国際規格が決めます。
以下のURLで規格書を見ることができます。
https://wg5-fortran.org/
さて、Fortran90 規格 § 2.5.2 "Keyword"で、以下のような記述がされています。
A word that is part of the syntax of a statement is a statement keyword. These keywords are not reserved words; that is, names with the same spellings are allowed. Examples of statement keywords are: IF, READ, UNIT, KIND, and INTEGER.
キーワードと同じ名前を使うことが明示的に許されているようですね。
というわけで、それがコードとして良いか悪いかは別として、上記のコードは正しいようです。コンパイラはキーワードと同じ名前の変数なり何なりが出てきても、ちゃんとコンパイルできなければなりません。そうでなければFortran規格準拠コンパイラではなくなってしまいます。コンパイラ開発者大変そうだな
もちろん、このようなコードは可読性を圧倒的に損なうので、やってはいけません。やってはいけませんが、面白いので誰かのSAN値を削るための精神攻撃としてはとても有効に使えるのではないでしょうか。