Fortran debugging error for array negtivel index

I have a test program here:

program test implicit none integer(4) :: indp integer(4) :: t1(80) indp = -3 t1(indp) = 1 write(*,*) t1(indp) end program test 

line 8 is incorrect because indp is a negative number. but when I compile it, use "ifort" or "gfortran", both of them cannot find this error. and even use valgrind to debug this program, it also cannot find this error. Do you have any ideas finding this problem?

+4
source share
2 answers

Fortran compilers are not required to inform you of such things; and, generally speaking, t1 (-3) = 1 can be a perfectly reasonable statement if you set the lower bound of your fortran array to be equal to or less than -3, for example

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

certainly allow you to install and read t1 (-3).

If you want to make sure that these errors are checked at runtime, you can compile with -fbounds-check with 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) 

or -check bounds in 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 

The reason valgrind doesn't catch it is a bit subtle, but note that if the array were allocated:

  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) 
+6
source

There are no errors. You declared indp as an integer of a certain range and precision (defined by KIND <- search for help for this term), which can be either positive or negative.

After that, you assigned the value 1 to t1(indp) and wrote it down.

+1
source

Source: https://habr.com/ru/post/1393549/


All Articles