No error when out of bounds using allocatable arrays

I am using gfortran 9.3.0 and I have found out that when I use an allocatable array there are not warnings nor errors when accessing out of the bounds indexes:

integer, allocatable:: data(:)
integer:: total(10)
...
allocate(data(10))
...
data(20) = 7           ! It is ok   
total(20) = 7          ! Error

Can you help me to avoid this or almost get a warning? Thank you

1 Like

I’ve wrapped your code into a small program and get the following warning when compiling with gfortran 11.1.0:

test.f90:8:6:

    8 | total(20) = 7          ! Error
      |      1
Warning: Array reference at (1) is out of bounds (20 > 10) in dimension 1

While this is useful for simple cases, it will not work in real life cases when the size of the array depends on some user input (if 10 is not changing, why use allocatables at all? In that case, you’re probably better off with using dimension(10)).

To detect out of bounds access at runtime, use the -fcheck=all option. From my experience, such runtime checks work best if the code is compiled without optimization. There are several other settings for useful compile-time and run-time checks, I use the options given DAMASK/cmake at master · eisenforschung/DAMASK · GitHub for gfortran and ifort, they are also fairly well documented. I assume fpm has a similar set of useful defaults.

1 Like

What I expect is to get an error due this silent behavior can drive into an error.

Now I think, my problem is that I have used the restricted word “data”.

you get the same behavior when renaming data and there is nothing wrong with using it as a variable name.

You don’t get an error during compilation for the allocatable array because it’s shape can change. Therefore, the compiler can detect out of bound errors only for simple toy problems where allocatable does not really make sense. As soon as the number of elements depends on user input, an out of bound access can be detected only during runtime, not during compile time. That is exactly what -fcheck=all does. The error message when running your code is

At line 7 of file test.f90
Fortran runtime error: Index '20' of dimension 1 of array 'data' above upper bound of 10
1 Like

I had the same problem some time ago. To be more precise: I accessed an array out of bounds and didn’t realised it, because with -O0 everything worked fine. Only when using compiler optimisation it gave me an segmentation fault.
But that’s not all: valgrind could detect the error in the unoptimised version, I think because the memcheck tracks every allocate/deallocate and then realised there was something wrong.
I’m not that experienced with valgrind, but I definitely recommend to use it whenever you are allocating memory.

In Fortran the workflow that I recommend is to always develop in “Debug” mode, where you enable -fcheck=all (in gfortran) and other debugging options. I recommend: -Wall -Wextra -Wimplicit-interface -g -fcheck=all -fbacktrace -ffpe-trap=invalid,zero,overflow -finit-real=snan -finit-integer=-99999999. Have tests, make sure all tests run, and you have no warnings/errors at compile time or runtime.

Then for production you compile in “Release” mode. I personally use -O3 -march=native -ffast-math -funroll-loops, but you can use whatever options work for your project. Run tests again to ensure things still work as expected (as sometimes the aggressive optimizations such as -ffast-math change answers a bit, so one must check that everything still works).

4 Likes