Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

O3 creates an infinite loop

AlexRichert-RedLine
496 Views

Using ifx (IFX) 2023.2.0 20230721 (CentOS 8 stream w/ kernel 6.2.1), I compile the following code:

program alextest
implicit none
integer :: my_int_array(100)
integer :: my_integer
integer :: my_indices(8) = (/ 8, 8, 8, 8, 9, 14, 19, 11 /)

my_int_array = 0

do my_integer = 1, 8
print*, my_integer
end do

! adding this line causes the loop to continue
! incrementing 'my_integer' forever:
my_int_array(my_indices(my_integer)) = 99

end program alextest

 

with the following lines:

ifx -O3 alextest.F90 -o alextest.x

 

The output consists of infinitely incremented values of 'my_integer' inside the do loop. I can get the desired behavior-- outputting integers 1 through 8-- by removing the 'my_int_array' line, or by disabling O3 (it works fine with O0 and O1; with O2 it prints the correct output but segfaults at the end, though that may be an unrelated issue).

1 Solution
jimdempseyatthecove
Honored Contributor III
483 Views

The exit value of your do loop leaves the loop control variable (my_integer) with the value of 9.

This value exceeds the size of the array my_indecies, and thus a "junk" value is used to index the array my_int_array.

This is the cause of the segfault.

 

Note, "not crashing" and "giving the desired behavior" is not the same as working properly.

Also, when the "junk" index produces an address within your process's virtual memory (R/W segment), that you just overwritten something that you should not have overwritten. The fact that the program does not crash (or produces the correct result) is no indication that it is running correctly.

 

Had you compiled this with full runtime checks enabled, you would have received an error message stating you index an array outside of its bounds.

 

Jim Dempsey

View solution in original post

3 Replies
jimdempseyatthecove
Honored Contributor III
484 Views

The exit value of your do loop leaves the loop control variable (my_integer) with the value of 9.

This value exceeds the size of the array my_indecies, and thus a "junk" value is used to index the array my_int_array.

This is the cause of the segfault.

 

Note, "not crashing" and "giving the desired behavior" is not the same as working properly.

Also, when the "junk" index produces an address within your process's virtual memory (R/W segment), that you just overwritten something that you should not have overwritten. The fact that the program does not crash (or produces the correct result) is no indication that it is running correctly.

 

Had you compiled this with full runtime checks enabled, you would have received an error message stating you index an array outside of its bounds.

 

Jim Dempsey

jimdempseyatthecove
Honored Contributor III
481 Views

Analog to think about

 

Imagine you are at a gun range. You slip an ammo clip with 8 rounds in it into your pistol, but you forgot about one in the chamber. You take your 8 shots at the target, getting the expected behavior. But when you holster your pistol, you have an accidental discharge.

 

Now then, if the bullet misses your foot. Is the program running properly?

 

Jim Dempsey

0 Kudos
AlexRichert-RedLine
470 Views

Thanks Jim, I have learned a valuable lesson about do loops in Fortran-- I had no idea it incremented the index a further time following the loop. Thanks for your help.

0 Kudos
Reply