forums.silverfrost.com Forum Index forums.silverfrost.com
Welcome to the Silverfrost forums
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Array Bounds checking

 
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> Support
View previous topic :: View next topic  
Author Message
steveDoyle



Joined: 04 Sep 2009
Posts: 108
Location: Manchester

PostPosted: Fri Sep 26, 2014 11:55 am    Post subject: Array Bounds checking Reply with quote

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
Back to top
View user's profile Send private message
IanLambley



Joined: 17 Dec 2006
Posts: 490
Location: Sunderland

PostPosted: Fri Sep 26, 2014 12:43 pm    Post subject: Reply with quote

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
Back to top
View user's profile Send private message Send e-mail
steveDoyle



Joined: 04 Sep 2009
Posts: 108
Location: Manchester

PostPosted: Fri Sep 26, 2014 1:08 pm    Post subject: Reply with quote

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
Back to top
View user's profile Send private message
JohnCampbell



Joined: 16 Feb 2006
Posts: 2554
Location: Sydney

PostPosted: Tue Sep 30, 2014 1:34 am    Post subject: Reply with quote

Steve,

Try the following change, as it appears that ftn95/sdbg keeps track of the original array size.
Code:
! 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
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> Support All times are GMT + 1 Hour
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group