#Fortran での bool値 の初期値宣言にまつわるエラー
- はじめに
fortran95 で以下のプログラムを作成中におかしなエラーに遭遇したので書いてみる。
- 課題: 初期値を .true. で宣言したはずの変数flagが、勝手に .false. へとプログラム内で変更される
まずはプログラムの内容から
module mod_qs
public :: main_qs
contains
subroutine main_qs( &
!inout変数
)
implicit none
logical :: flag = .true.
!変数チェック
write(6,*) ' 1 ' , flag
!メインとなるループ
do while (flag)
....
end do
end subroutine main_qs
end module
1.まずはテストのために、このサブルーチンだけを呼び起こす**(問題なしケース)**
program test
call main_qs
end test
1 T
初期宣言で True としてるので、こうなるはず!
2. 巨大なメインプログラムから呼び出したサブルーチン(親)内で、このサブルーチンを呼び出す**(問題ありケース)**
program main
call test
end program
subroutine test
call main_qs
end subroutine test
1 F
初期宣言で True としてるはずなのに、なぜかプログラム内で勝手にfalseに置き換わってる!
- とりあえずの解決策
=> 初期値をプログラム内で宣言することで正常動作
subroutine main_qs( &
!inout変数
)
implicit none
logical :: flag
flag = .true.
!変数チェック
write(6,*) ' 2 ' , flag
!メインとなるループ
do while (flag)
....
end do
end subroutine main_qs
2 T
もちろん、bool 宣言ではなく、0,1のinteger や、初期化するモジュールないし場所をプログラムで設ければ問題は解決するはずですが、
よく、私自身logicalをプログラムで使うので、記事にまとめました。
問題解決
cure_honey さんから下記のようなアドバイスをいただきました。ありがとうございます!
結果的に、下記のコメントのとおり、**Fortranでは、サブルーチン内の変数宣言で初期化した値は、2回目以降の呼び出しでは反映されず、前回の操作結果の値を保持する(別個に初期値を設定する箇所を設ける必要がある)**という仕様?が原因となっていました。
C言語等とは異なり、少し混乱するようなところでした。
まだまだFortranの勉強が足りないようです(笑)
簡単なデモ等を作成し、確認してみました。C言語でも同様のコードを作成し、違いを見てみました。その結果を下記に記載します。
- 実際に確認してみた!
1 program test
2 implicit none
3
4 integer, parameter :: n = 10
5 integer :: i
6
7 do i = 1, n
8 call main_qs( &
9 i & ! IN
10 )
11 end do
12
13 end program test
14
15 subroutine main_qs( &
16 ii & ! IN
17 )
18 implicit none
19
20 integer, intent(in) :: ii
21 logical :: flag = .true.
22 integer :: j
23
24 write(6,*) 'Visit This SUB. Number ', ii , ' FLAG == ', flag
25
26 do while ( flag )
27 do j = 1, ii
28 if ( j == ii ) then
29 flag = .false.
30 end if
31 end do
32 end do
33
34 return
35 end subroutine
Visit This SUB. Number 1 FLAG == T
Visit This SUB. Number 2 FLAG == F
Visit This SUB. Number 3 FLAG == F
Visit This SUB. Number 4 FLAG == F
Visit This SUB. Number 5 FLAG == F
Visit This SUB. Number 6 FLAG == F
Visit This SUB. Number 7 FLAG == F
Visit This SUB. Number 8 FLAG == F
Visit This SUB. Number 9 FLAG == F
Visit This SUB. Number 10 FLAG == F
- C言語でも試してみた!
1 #include <stdio.h>
2 #include <stdbool.h>
3
4 void main(void)
5 {
6 int n = 10;
7 int i;
8 for(i=0; i<n; i++ ){
9 main_qs( i );
10 }
11 }
12
13 int main_qs( int ii )
14 {
15 bool flag = true;
16 int j = 0;
17
18 printf(" Visit This SUB. Number %d",ii ) ;
19 printf(" FLAG = %d \n", flag ) ;-
20
21 while ( flag ){
22 while( j <= ii ){
23 if ( j == ii ){
24 flag = false;
25 }
26 j++;
27 }
28 }
29 }
Visit This SUB. Number 0 FLAG = 1
Visit This SUB. Number 1 FLAG = 1
Visit This SUB. Number 2 FLAG = 1
Visit This SUB. Number 3 FLAG = 1
Visit This SUB. Number 4 FLAG = 1
Visit This SUB. Number 5 FLAG = 1
Visit This SUB. Number 6 FLAG = 1
Visit This SUB. Number 7 FLAG = 1
Visit This SUB. Number 8 FLAG = 1
Visit This SUB. Number 9 FLAG = 1
ということで、fortran で初期宣言するときは気を付けていかないといけませんね。