Silverfrost Forums

Welcome to our forums

Array Bounds checking

26 Sep 2014 10:55 #14712

Since moving from FTN77 to FTN95 (7.10.0) many of my trusted stable applications are exhibiting odd behaviour (random crashes in %gr subsystems (draw_character@) /add_menu_item@/random freezing of app on loss of focus). As all my applications use shared sub-function i would expect the behaviour to be consistent across application which they are not. I am assuming is due to internal overwriting issues or undefined vars in the code. In an attempt to isolate these problems i recompile everything using /FULL_UNDEF which fails to highlight any problems

The help for /full_undef state it does bounds checking on arrays but it does not complain at the following code

program test integer fred(100,10) fred(1,1) = 1 fred(100,10) = 1000 call bert(fred) end

  subroutine bert(x)
  integer x(100)
  call eric(x)
  end
  
  subroutine eric(y)
  integer y(10,100)
  write(*,*) 'y(1,1) = ', y(1,1)
  write(*,*) 'y(100,10) = ', y(10,100)
  end
  

Any ideas or suggestion appreciated

26 Sep 2014 11:43 #14713

In the main program, 'FRED' has 1000 elements stored adjacent to each other and therefore that space is allocated, i.e. 4000 bytes. This is ten groups of one hundred and FRED(1,1) to FRED 100,1) come first in the storage of bytes. Then FRED(1,2) to FRED(100,2) etc. You can think of it as just a vector of bytes rather than a matrix of variables.

Passing FRED to BERT and calling it 'X' with 100 elements, only means that the first 100 elements of 'FRED' are used as 'X' within BERT, an attempt to access X(101) for example would produce a run-time error.

Passing X to ERIC and calling it Y dimensioned to contain another 1000 elements still points to the same data. Only within each routine will a bounds check be perormed if the subscripts exceed the definition.

Calling a suproutine with an array name really only passes the address of the first element of the array. it is up to the programmer to only access array elements that exist. This is run time and certainly can't be picked up at compile time.

If you called a subroutine like this:

Call bert(fred(2,5))

This simply passes the address of that element and the array X within BERT is assumed to start at that point. This subroutine assumes that you only want to access 100 elements of an array.

Sorry for being no help. Ian

26 Sep 2014 12:08 #14714

Ian

When I started it was using Fortran iV so am very familiar with the technique of changing the shape allocated memory by passing either sub addresses or changing the index in the calls .everything is OK unless you inadvertently exceed the allotted memory. I just had a vague recollection that the complier performed additional runtime checks if the correct options are used

thqanks

steve

30 Sep 2014 12:34 #14749

Steve,

Try the following change, as it appears that ftn95/sdbg keeps track of the original array size.

! file bound.f90
program test 
 integer fred(100,9) 
 fred(1,1) = 1 
 fred(100,9) = 1000 
 call bert(fred) 
 end 

 subroutine bert(x) 
 integer x(100) 
 call eric(x) 
 end 

 subroutine eric(y) 
 integer y(10,100) 
 write(*,*) 'y(1,1) = ', y(1,1) 
 write(*,*) 'y(100,9) = ', y(10,90) 
 write(*,*) 'y(100,10) = ', y(10,100) 
 end 

I found that ftn95 bound.f90 /lgo worked, but ftn95 /check /lgo gave an error at the call to eric

John

Please login to reply.