我在这里有一个测试程序:
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来调试这个程序它也找不到这个错误。 你有什么想法找到这种问题吗?
答案 0 :(得分:6)
Fortran编译器不需要向您发出有关此类内容的警告;通常,如果将fortran数组的下限设置为等于或小于-3的值,则t1(-3)= 1可能是一个非常合理的语句,例如
integer(kind=4), dimension(-5:74) :: t1(80)
肯定会允许设置和读取t1(-3)。
如果要确保在运行时检查这些类型的错误,可以使用gfortran与-fbounds-check
进行编译:
$ 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)
在ifort中或-check bounds
:
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)
答案 1 :(得分:1)
没有错误。您将indp
声明为某个范围和精度的整数(某个 KIND < - 在该术语的帮助中查找),可以是正数也可以是负数。
之后,您将1
的值分配给t1(indp)
并将其写出来。