5

我在这里有一个测试程序:

  program test  
  implicit none  

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

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

  end program test

第 8 行是错误的,因为 indp 是负数。但是当我编译它时使用'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 bounds在 ifort 中:

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为某个范围和精度的整数(某种类型< - 在该术语的帮助中查找),它可以是正数或负数。

之后,您将值分配1给 ant1(indp)并将其写出来。

于 2012-01-28T21:50:22.767 回答