Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

array out of bounds: warning, error or up the compiler?

1,563 views
Skip to first unread message

Anton Shterenlikht

unread,
Nov 13, 2013, 6:35:18 AM11/13/13
to
It seems I fundamentally mis-understood
the array bounds checking issue.
If array bounds checking is requested
from the compiler, what should the compler
do when it detects the out of bounds reference
happening: issue a warning or an error?

For example, this code:

integer :: i, a(10)

do i=1,size(a)+1
a(i) = 1
end do

write (*,*) sum(a)
end

will run correctly, i.e. sum(a) is correct,
as long as there are no bounds checks.
When the bounds checks are on, gfortran and ifort
give errors, while crayftn gives a warning and
the answer:

$ gfortran -fbounds-check z.f90
$ ./a.out
At line 4 of file z.f90
Fortran runtime error: Array reference out of bounds for array 'a', upper bound of dimension 1 exceeded (11 > 10)

$ ifort -check bounds z.f90
$ ./a.out
forrtl: severe (408): fort: (2): Subscript #1 of the array A has value 11 which is greater than the upper bound of 10

$ftn -Rb z.f90
$

Then at runtime:

lib-4962 : WARNING
Subscript 1:11:1 is out of range for dimension 1 for array
'a(*)' at line 4 in file 'z.f90' with bounds 1:10.
10

So are compilers allowed to issue a warning
or an error in this case as they see fit?

Thanks

Anton

Arjen Markus

unread,
Nov 13, 2013, 6:56:43 AM11/13/13
to
On Wednesday, November 13, 2013 12:35:18 PM UTC+1, Anton Shterenlikht wrote:
> It seems I fundamentally mis-understood
> the array bounds checking issue.
>
...
>
>
> So are compilers allowed to issue a warning
> or an error in this case as they see fit?
>
> Thanks
>

The thing you are wrong about is assuming that your program runs correctly without the array bound checking on. It does not. It is just that in this simple case there are no visible side effects.

In fact however, if the do-loop was part of a larger routine/program it could have overwritten some variable, because it just happens to be next to the "a" array in memory. This sort of things can lead to very mysterious bugs.

I tried your program with gfortran 4.5 (yes, an oldie) and the resulting executable simply gets into an endless loop. But if I add a write-statement to see what it is doing, the endlessness disappears - these are typical symptoms of such a bug.

Regards,

Arjen

Richard Maine

unread,
Nov 13, 2013, 10:34:31 AM11/13/13
to
Anton Shterenlikht <me...@mech-aslap33.men.bris.ac.uk> wrote:

> It seems I fundamentally mis-understood
> the array bounds checking issue.
> If array bounds checking is requested
> from the compiler, what should the compler
> do when it detects the out of bounds reference
> happening: issue a warning or an error?

"Should" according to what criterion? This has nothing to do with the
standard, which has no requirement at all relating to array bounds
checking. The standard says that the user code in question is in
violation, but that's all. The compiler can do anything at all with such
code.

I'd say that the compiler "should" do whatever its documentation claims
in regard to array bounds checking, and that it should have such an
option. But those are quality of implementation matters - not
requirements of the standard.

> For example, this code:
[elided]
> will run correctly, i.e. sum(a) is correct,
> as long as there are no bounds checks.

That is not at all guaranteed. Any number of things could happen instead
of running corectly. The out-of-bounds array reference could cause a
segmentation fault. Or it could overwrite something elsewhere in the
program. Not much elsewhere in the program shown, but it could overwrite
something in the I/O routines such that the final write statement
failed. Odds are probably against that happening in this particular
case, but there is no guarantee. When you exceed array bounds,
*ANYTHING* can happen according to the standard. Occasionally what
actually happens can seem pretty strange; I recommend against assuming
you know how such programs will act in general.

--
Richard Maine
email: last name at domain . net
domain: summer-triangle

glen herrmannsfeldt

unread,
Nov 13, 2013, 1:06:25 PM11/13/13
to
Anton Shterenlikht <me...@mech-aslap33.men.bris.ac.uk> wrote:

> It seems I fundamentally mis-understood
> the array bounds checking issue.
> If array bounds checking is requested
> from the compiler, what should the compler
> do when it detects the out of bounds reference
> happening: issue a warning or an error?

> For example, this code:

> integer :: i, a(10)

> do i=1,size(a)+1
> a(i) = 1
> end do

> write (*,*) sum(a)
> end

> will run correctly, i.e. sum(a) is correct,

sum(a), and the contents of a, are likely correct, but
whatever is in memory after a is likely wrong.

In many cases, bounds check can only be done at run time,
but in this case it isn't hard for the compiler to notice.

Cray compilers have a history of optimizing DO loops,
especially on machines with vector registers. It is pretty
easy for the compiler to notice that i goes to 11, and a(11)
is past the end of a.

> as long as there are no bounds checks.
> When the bounds checks are on, gfortran and ifort
> give errors, while crayftn gives a warning and
> the answer:
>
> $ gfortran -fbounds-check z.f90
> $ ./a.out
> At line 4 of file z.f90
> Fortran runtime error: Array reference out of bounds for array 'a',
> upper bound of dimension 1 exceeded (11 > 10)

Reasonably often fetch from outside an array doesn't cause problems,
and issuing a warning and continuing might not be a bad thing.

Storing outside an array is best handled as a fatal error.

In the early days of Fortran (before the assumed size (*) was added)
it was usual to dimension dummy arrays as (1). As long as you stayed
inside the actual array, and no bounds check was done, that worked.

More recently, compilers will detect at least constant subscripts at
compile time, and even, as you note DO loops, that exceed the declared
dimension.

Just fix them!

-- glen

robin....@gmail.com

unread,
Nov 13, 2013, 5:30:39 PM11/13/13
to
On Wednesday, November 13, 2013 10:35:18 PM UTC+11, Anton Shterenlikht wrote:
> It seems I fundamentally mis-understood the array bounds checking issue. If array bounds checking is requested from the compiler, what should the compler do when it detects the out of bounds reference happening: issue a warning or an error? For example, this code:
> integer :: i, a(10)
> do i=1,size(a)+1
> a(i) = 1
> end do
> write (*,*) sum(a)
> end

> will run correctly,

No, it doesn't run correctly.
The program contains an error, assigning the value 1 to a(11).
What is in location a(11)?
Its anybody's guess.
You were just lucky that the program (apparently) didn't corrupt
something important, such as another variable or destroy some code.

> i.e. sum(a) is correct, as long as there are no bounds checks.

sum(a) will most likely be "correct" because you are adding only
the values of a(1) through a(10).

robin....@gmail.com

unread,
Nov 13, 2013, 5:37:07 PM11/13/13
to
On Thursday, November 14, 2013 5:06:25 AM UTC+11, glen herrmannsfeldt wrote:
> Anton Shterenlikht <......men.bris.ac.uk> wrote:
>> It seems I fundamentally mis-understood > the array bounds checking issue. > If array bounds checking is requested > from the compiler, what should the compler > do when it detects the out of bounds reference > happening: issue a warning or an error? > For example, this code: > integer :: i, a(10) > do i=1,size(a)+1 > a(i) = 1 > end do > write (*,*) sum(a) > end > will run correctly, i.e. sum(a) is correct,

> sum(a), and the contents of a, are likely correct, but whatever is in memory after a is likely wrong.

The value in memory following array a won't be "wrong". It will be 1.
But that value would have destroyed whatever was in memory at that location.
If that value was that of a variable, it will have been altered (corrupted).
If that value was code, then that code will have been destroyed.
If that code is to be executed, the program will probably crash.
Whatever happens, it will be unpredictable.
0 new messages