🤖

【Fortran】block文でインスタントに変数を使う

2022/10/11に公開

TL;DR

subroutineの受け皿などで一時的に使う変数を作りたいとき、block文を使うことでprocedureの先頭まで戻らずに変数宣言することできます。

前置き

Fortranで変数を使うとき、変数を宣言する必要があります((implicit noneする場合))。変数宣言はsubroutineやfunction (procedure)内ですべての手続きの前に行う必要があり、一時的に変数を使いたいだけという場合でもprocedureの先頭まで戻る必要がありました。

よくないサンプル
subroutine long_long_subroutine()

!
!... 1000行くらいあるコード
!

! このIUNITを定義したくなったらsubroutineの先頭までスクロールして宣言する必要がある
open(newunit=IUNIT,file="myfile.txt")

そこで、Fortran2008からはblock構文が用意されました。block構文を使うとローカルな変数スコープを用意することができ、その中で一時的な変数を定義することができます。

先の例のように、open文でunitを受けるための整数を定義したいとします。通常であればsubroutineのすぐ下で宣言する必要があります。

blockを使わないサンプル
subroutine long_long_subroutine()
  integer :: IUNIT
  
  !
  !... 1000行くらいあるコード
  !

  open(newunit=IUNIT,file="myfile.txt")
  !...

block文を使うことで、openのすぐ近くで変数を定義することができます。

block文を使うサンプル
subroutine long_long_subroutine()
  
  !
  !... 1000行くらいあるコード
  !

  block
    integer IUNIT 
    open(newunit=IUNIT,file="myfile.txt")
    write(IUNIT,*) xx
    close(IUNIT)
  end block
  
  ! ここから先はIUNITにはアクセスできない
  !...

block文を使うことで、C++での{}のようにコードブロックが作られます。blockの中で定義した変数はend block以降はアクセスすることはできません。

注意

block文で定義できるのはあくまでblockの中でのみ有効な変数です。blockの外からもアクセスされるような変数はblock文を使わずにprocedureの先頭で宣言する必要があります。面倒だからといってblockを連発したりネストしたりすると変数のスコープがめちゃくちゃになって非常にわかりにくいコードになるので、本当に一時的にしか使わない変数でだけ使うようにしましょう。

参考

https://qiita.com/implicit_none/items/55c47407aa376277a531

Discussion