Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why no runtime error when clearly writing over array bounds?

I have a program that assigns an array beyond it's bounds, and I was expecting a run-time error to be thrown. Yet no error is raised at all and the program proceeds to write into undeclared memory. Is there some compiler option to guard against this? With the memory dump shown it is clear this overreach of bounds is real. Is there a way to declare variables or argument specs to catch this? Obviously this is a clear case, but when tasked to maintain thousands of lines of F77 derived code it is not always clear (to me) if this might be happening.

PROGRAM TEST_CODE
IMPLICIT NONE

INTEGER*4 :: R(5)           ! Array of 5

    CALL R_TEST(R, 10)

END PROGRAM

SUBROUTINE R_TEST(R, J)
IMPLICIT NONE

INTEGER*4, INTENT(INOUT) :: R(1)    ! Dummy is array of 1
INTEGER*4, INTENT(IN) :: J
INTEGER*4 :: K

DO K=J-5,J+5            ! K=5..15
    R(K) = K            ! No Runtime Error
END DO

END SUBROUTINE

Compiler is Intel Fortran 2011 XE, and yes I am using the byte spec INTEGER*4 because I know what I get with it.

Here are the compiler options for runtime checking. Compiler Options

Memory of <code>R</code> variable

like image 621
John Alexiou Avatar asked Mar 23 '12 14:03

John Alexiou


People also ask

Is array out of bounds a runtime error?

The ArrayIndexOutOfBoundsException is a runtime exception in Java that occurs when an array is accessed with an illegal index. The index is either negative or greater than or equal to the size of the array.

Will overflow cause a runtime error?

Integer overflow itself may not cause run time error, but it can indirectly cause run time error, as in above example.

Why does C++ allow out of bounds?

It is not a class. Further, C++ is also built on another rule which makes bounds-checking non-ideal. The C++ guiding principle is "you don't pay for what you don't use". If your code is correct, you don't need bounds-checking, and you shouldn't be forced to pay for the overhead of runtime bounds-checking.


1 Answers

The intel compiler does a very good job on bounds checking for the pointer and allocatable arrays. If you slightly modify your code (below) and compile with something like:

$ ifort -O0 -debug -traceback -check -ftrapuv TEST_CODE.f90

you will get a run time error. But for assumed size arrays the intel compiler cannot check the bounds. Especially for F77 codes with implicit typing and so on it won't be easy to find memory leaks. Another tiny thing, in Fortran your program has to do something meaningful; otherwise the compiler will omit your code because it simply does nothing! That's why I added a print in the end.

There is a small problem with R(:) thing is that the compiler cannot assume that it is contiguous in the memory; hence it cannot make some compiler optimization. It would then be better to use allocatable arrays or use the contiguous attribute (F2008 standard).

PROGRAM TEST_CODE
IMPLICIT NONE

INTEGER*4 :: R(5)           ! Array of 5

    CALL R_TEST(R, 10)
    print *,R

END PROGRAM

SUBROUTINE R_TEST(R, J)
IMPLICIT NONE

INTEGER*4, INTENT(INOUT) :: R(:)    ! Dummy is array of 1
INTEGER*4, INTENT(IN) :: J
INTEGER*4 :: K

DO K=J-5,J+5            ! K=5..15
    R(K) = K            ! No Runtime Error
END DO

END SUBROUTINE
like image 84
Hossein Talebi Avatar answered Sep 21 '22 14:09

Hossein Talebi