Array indexing

Array indexing

I have an array that is defined like so:

COMMON/KEYS/KEYNR(42,50),KDIAG(12)

CHARACTER*4 CKEYNR(42,50)

EQUIVALENCE (CKEYNR,KEYNR)

And used like this:

DO 605 K=1,2100

605 KEYNR(K,1)=0

And I'm getting the following error:

forrtl: severe error (408): fort: (2): Subscript #1 of the array KEYNR has value 43 which is greater than the upper bound of 42

Any suggestions on how to fix this will be appreciated. Note that I, unfortunately, require a compiler-based fix and not a code fix, as this is an ancient 10,000+ line FORTRAN code base, with similar loops throughout, and works right now with 4 other compilers/platforms and I'm pretty sure any code change will introduce issues elsewhere.

Thanks,

-k.

14 posts / novo 0
Último post
Para obter mais informações sobre otimizações de compiladores, consulte Aviso sobre otimizações.

You have not shown the dimensions specified for array KEYNR. What are they? I would guess INTEGER*4 KEYNR(2100,1) would work.

Oops sorry. I've edited the post to show that. It is defined like so:

COMMON/KEYS/KEYNR(42,50),KDIAG(12)

I could be wrong but it looks like you need either another equivilance with the one-dimensional intepretation or you need to turn off array bounds checking.

The newer compilers are fairly intollerant of code that does not conform to the standards. One good reason to indulge the compiler in its intollerance is that nonconforming code may disable optimization.

In the example you've shown, it will work ok if you turn off array bounds checking.

The code is counting on the way that arrays are laid out in memory. In memory the array elements are laid out like this:

KEYNR(1,1)

KEYNR(2,1)

KEYNR(3,1)

so by writing the loop like it is, the code is setting 2100 consecutive words to 0, all of which are part of the

KEYNR array. This is the sort of "clever" programming you sometimes run into in old code where speed was

more important than clarity.

In modern Fortran, you could replace this with

KEYNR = 0

I know this post is super old but no one really addressed this guys problem (I stumbled across this post while trying to solve another problem of my own).

KEYNR(42,50) has 2100 array slots (42x50=2100). He is trying to initialize all the (i,j) array slots to the value to zero.

The problem is that in the initializing loop he is incrementing the i value from 1 to 2100 and fixing j value at 1, so the array he is attempting to zero has the dimensions KEYNR(1:2100,1). Since he defined the array as KEYNR(1:42,1:50) (by default arrays start as 1 in Fortran unless otherwise specified) the compiler is giving him a out of bounds error when the loop tries to set KEYNR(43,1)=0.

The correct solution is not to turn off bounds checking but to code the proper loop as follows:

DO J=1,42

DO K=1,50
KEYNR(J,K)=0
END DO
END DO

I know this is a simple problem but I figure it's worth posting a solution in case someone new to programming or new to Fortran comes across this post.

Ashley, I think he knows that. The code took advantage of a lack of array bounds checking and the knowledge that Fortran arrays are in column-major order so the loop to initialize 2100 elements would, in the absence of bounds checking, actually initialize the 42x50 array.

You are correct, of course, that this is not legal Fortran and that bounds checking would complain. You are also correct on the proper fix. But he said at the outset that he didn't want to change the code and wanted a way to tell the compiler to ignore the error.

Steve - Intel Developer Support

I am getting similar error involving array indixing in my code for the array defined as follows in main program. The array is returned from a subroutine that reads a text file via dummy array :

 real,dimension(:), allocatable :: co2ser(:)

allocate (co2ser(1:30)) 

The program compiles without erro but the executable returns this error when I run it:

"forrtl: severe <408> fort: <11>: subscript #1 of the array CO2SER has value 0 which is less than the lower bound of 1."

The array was populated from a text file (unit=11) with a vector of 30 elements (30x1) by a subroutine in a module. I know which array is causing the problem just don't know how to fix it.

Any help is appreciated.

Thank you

You have to locate the portion of code where the array is being referenced with an out-of-bounds index (index = 0 in your case). If you use the /traceback option, in addition to the current options that trapped the invalid subscript, you will find the segment(s) of code that you need to fix.

Isn't this the intel compiler's bug reported earlier ( http://software.intel.com/en-us/forums/topic/335404) concerning allocatable array assignment error because my array is allocatable and I am using Frortan 12

Thanks

>> real,dimension(:), allocatable :: co2ser(:)

 

The above syntax would declare an array of arrays (witout using a user defined type). I think this is illegal syntax (except for character). Steve or IanH may have more athoratative input.

Jim Dempsey

www.quickthreadprogramming.com

I am not sure what was intended with:

 

real,dimension(:), allocatable :: co2ser(:)
allocate (co2ser(1:30)) 

But I had a look under debug and this declaration gives you get a one dimensional real array with elements 1 to 30. Your error message says you referenced element zero which is indeed an error as 0 is not in the 1 to 30 range.

I am not sure what your code was expecting, did you really want to allocate co2ser(0:29)?  But whatever, some rework is required!

I would suggest posting a more complete code sampe and someone will be more able  to assist.

Andrew

 

The two specifications of (:) there are redundant. I'd have to check the standard to see if it's allowed to have both...

Steve - Intel Developer Support

Dear all,

Thank you for all your comments and helps. Every suggestion you provided was helpful as  I finally found where the problem was. The codes for allocating and defining the array were correct in terms of syntax. However, the parameter (k=1,30), which I used to get elements of co2ser (one at a time) was supposed to be provided by second subroutine but it happend that it only makes k aviable after the third subroutine looking for elements of co2ser attempted to get the values in co2ser array and as a result co2ser(k) could not be reurned. I fixed that and now it works.    

Thanks again

Deixar um comentário

Faça login para adicionar um comentário. Não é membro? Inscreva-se hoje mesmo!