Silverfrost Forums

Welcome to our forums

Interesting bug in array initialisation

24 Mar 2016 3:14 #17338

so, as a test, i put together this piece of code:

!ftn95$free
PROGRAM TEST
  INTEGER :: IARRAY(50)
  
  IARRAY(1:50)  = 0
  IARRAY(0:50)  = -1
  IARRAY(1:51)  = -2
  DO I=0,51
   IARRAY(I)=I
  END DO
  
END PROGRAM   

Compiling it with /undef gives two warnings (note, not errors) at lines 6/7.

Running it under SDBG, it steps over the first line OK, but hangs on the second line.

this is with ftn95 v8.00 beta.30.

K

edit: it gives the same warnings using /DEBUG but doesn't 'hang' in SDBG.

second edit:

i changed the code slightly...

!ftn95$free
PROGRAM TEST
  INTEGER :: IARRAY(50)
  
  I1=1;I2=50;  IARRAY(I1:I2)  = 0
  I1=0;I2=50;  IARRAY(I1:I2)  = -1
  I1=1;I2=51;  IARRAY(I1:I2)  = -2
  DO I=0,51
   IARRAY(I)=I
  END DO
  
END PROGRAM  
 

now, there's no errors during compilation, the program doesn't hang under SDBG, but i don't get a runtime error about the array subscripts being out of bounds until the line in the DO loop.

K

17 Apr 2016 6:50 (Edited: 12 May 2016 12:52) #17436

At first glance, this bug report seemed uninteresting, since it relates to the run-time behavior of buggy code. However, I came back to this post after a few weeks, took a deeper look, and found that the run time checking that earns affection for FTN95 has a quirk that should either be rectified or at least made known to users. For this discussion, it is sufficient to simplify the code to

PROGRAM TEST
  INTEGER :: IARRAY(50)
  IARRAY(0:50)  = -1
END PROGRAM

When this is compiled and run with /check, the program runs and nothing is output. My explanation is that array bounds errors that can be detected at compile time (as in this example) are reported at compile time, and no corresponding bounds checking code is inserted into the OBJ and EXE generated from this compilation. The compiler gives you a warning and, if you persist in linking and running the program despite the warning, you are on your own. The program does not give any run-time error messages because the third line did not generate any subscript-checking machine code.

When the same program is compiled with /undef, something even more unexpected happens. As with Kenny's slightly longer program, the program hangs. Why?

According to the FTN95 documentation, /undef implies /check, and this trivial program does not use any uninitialized variables; therefore, we should expect the EXE to run in an instant and produce no output. Why does it hang, instead?

I looked at the machine code and found the explanation. For the assignment IARRAY(0:50) = -1 the compiler implements this array assignment with a machine code loop similar to:

     DO II = 0, 50
        IARRAY(II) = -1
     END DO

The undeclared loop index II is allocated on the stack, as is the local array IARRAY. The layout is:

     [EBP - 0xE4] : II
     [EBP - 0xE0] : IARRAY(1), the declared base of the array
     [EBP - 0xDC] : IAARAY(2)
   -- etc. --

Thus, perhaps unexpectedly, II and IARRAY(0) have the same machine address. As a consequence, when IARRAY(0) is set to -1, II also becomes -1, and the loop will be executed for ever: the program hangs.

The Fortran standard requires that a DO index variable should not be altered inside the DO loop, but typically 'non-conforming programs' can (mis)behave in any fashion. However, as a user I should like to have the compiler help me find the bug when I have requested assistance by specifying /check, /undef, etc., and it is not at all evident that the DO index variable is at risk.

P.S.: I find Kenny's 'this is with ftn95 v8.00 beta.30' puzzling. As far as I know, the beta compiler generates 64-bit code but does not yet accept any of the options /debug, /check and /undef.

18 Apr 2016 6:56 #17437

Thanks for this. I have logged this for investigation.

11 May 2016 7:51 #17470

This is an update on an earlier post today.

This issue has now been resolved by upgrading the warning message to an error report whenever /check (or options that imply /check) or /bounds_check is used on the command line.

This change will apply to the next full release (i.e. after 8.0).

Please login to reply.