5

ここにテストプログラムがあります:

  program test  
  implicit none  

  integer(4) :: indp  
  integer(4) :: t1(80)  

  indp = -3  
  t1(indp) = 1  
  write(*,*) t1(indp)  

  end program test

indpが負の数であるため、8行目では間違っています。しかし、コンパイル時に「ifort」または「gfortran」を使用すると、どちらもこのエラーを見つけることができません。valgrind を使用してこのプログラムをデバッグしても、このエラーは見つかりません。この種の問題を見つけるアイデアはありますか?

4

2 に答える 2

7

Fortran コンパイラは、このようなことについて警告を出す必要はありません。また、一般に、fortran 配列の下限を -3 以下に設定した場合、t1(-3) = 1 は完全に合理的なステートメントになる可能性があります。

integer(kind=4), dimension(-5:74) :: t1(80)

確かに t1(-3) の設定と読み取りが許可されます。

これらの種類のエラーが実行時にチェックされることを確認したい場合は -fbounds-check、gfortran でコンパイルできます。

$ gfortran -o foo foo.f90 -fcheck=bounds
$ ./foo 
At line 8 of file foo.f90
Fortran runtime error: Array reference out of bounds for array 't1', lower bound of dimension 1 exceeded (-3 < 1)

または-check boundsiforで:

ifort -o foo foo.f90 -check bounds

$ ifort -o foo foo.f90 -check bounds
$ ./foo
forrtl: severe (408): fort: (3): Subscript #1 of the array T1 has value -3 which is less than the lower bound of 1

Image              PC                Routine            Line        Source             
foo                000000000046A8DA  Unknown               Unknown  Unknown

valgrind がこれをキャッチしない理由は少し微妙ですが、配列が割り当てられている場合はキャッチされることに注意してください。

  program test  
  implicit none  

  integer(kind=4) :: indp  
  integer(kind=4), allocatable :: t1(:)  

  indp = -3  
  allocate(t1(80))
  t1(indp) = 1  
  write(*,*) t1(indp)  
  deallocate(t1)

  end program test

$ gfortran -o foo foo.f90 -g
$ valgrind ./foo
==18904== Memcheck, a memory error detector
==18904== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==18904== Using Valgrind-3.6.1 and LibVEX; rerun with -h for copyright info
==18904== Command: ./foo
==18904== 
==18904== Invalid write of size 4
==18904==    at 0x400931: MAIN__ (foo.f90:9)
==18904==    by 0x400A52: main (foo.f90:13)
==18904==  Address 0x5bb3420 is 16 bytes before a block of size 320 alloc'd
==18904==    at 0x4C264B2: malloc (vg_replace_malloc.c:236)
==18904==    by 0x400904: MAIN__ (foo.f90:8)
==18904==    by 0x400A52: main (foo.f90:13)
==18904== 
==18904== Invalid read of size 4
==18904==    at 0x4F07368: extract_int (write.c:450)
==18904==    by 0x4F08171: write_integer (write.c:1260)
==18904==    by 0x4F0BBAE: _gfortrani_list_formatted_write (write.c:1553)
==18904==    by 0x40099F: MAIN__ (foo.f90:10)
==18904==    by 0x400A52: main (foo.f90:13)
==18904==  Address 0x5bb3420 is 16 bytes before a block of size 320 alloc'd
==18904==    at 0x4C264B2: malloc (vg_replace_malloc.c:236)
==18904==    by 0x400904: MAIN__ (foo.f90:8)
==18904==    by 0x400A52: main (foo.f90:13)
于 2012-01-28T23:23:48.663 に答える
1

エラーはありません。indp特定の範囲と精度の整数として宣言しました (特定のKIND <-その用語のヘルプを参照してください)。これは、正または負のいずれかになります。

その後、 の値1を anに代入しt1(indp)て書き出しました。

于 2012-01-28T21:50:22.767 に答える