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

error #5560: Subscript #1 of the array BUF has value 102 which is greater than the upper bound of 100

Bowman__Eric
Novice
2,786 Views

Still trying to compile the NASTRAN code and am seeing this: 

error #5560: Subscript #1 of the array BUF has value 102 which is greater than the upper bound of 100       

Here is an offending line of code: 

  402 IF ( BUF(4) .NE. 0 ) BUF(102) = BUF(102) + BUF(4) - 1

and here is the definition of BUF: 
 

  COMMON /SDR2X5/ BUF(100),BUFA(100)  ,BUFB(4176)


Somehow, this was compiling for the gents at NASA but it seems like it shouldn't, and if it did compile it seems like it would throw a runtime error.

I appreciate any guidance with this, I am trying to understand both how fortran 77 is usually put together (bad practices and all) and I am trying to learn good practices so that I can understand and fix legacy fortran codes well. 

Thanks!

Eric

 

0 Kudos
1 Solution
jimdempseyatthecove
Honored Contributor III
2,786 Views

It is better for the compiler to catch compile time errors when it can (you have a work around for array passed as scalar).

In this case, BUF(102) is clearly in error.

If your intention is to make BUF(101) equivalent to BUFA(1) then you must state so.

*** prior to fixing this, read the all the code that references BUF and BUFA to ascertain if BUF(101) is or is not to be equivalent BUFA(1). This is symptomatic of a programming error. Make no assumptions as to the original programmer's intent was. Look at the code and verify.

Jim Dempsey

View solution in original post

0 Kudos
16 Replies
JohnNichols
Valued Contributor III
2,783 Views

As far as I am aware you cannot declare an array of 100 and then access 102, successfully from an algorithmic viewpoint, but some compilers may not catch the error. 

One often gets this error -- it means you need to look for the overcount on the index. 

if it worked at NASA and their compiler did not pick it up and Intel's compiler is getting very sophisticated, so it picks it up -- then this is the problem with progress. 

Commons are a way to have many hidden errors - they were ok in the 70's as was bell bottomed trousers, but we have all learnt better. 

 

0 Kudos
jimdempseyatthecove
Honored Contributor III
2,787 Views

It is better for the compiler to catch compile time errors when it can (you have a work around for array passed as scalar).

In this case, BUF(102) is clearly in error.

If your intention is to make BUF(101) equivalent to BUFA(1) then you must state so.

*** prior to fixing this, read the all the code that references BUF and BUFA to ascertain if BUF(101) is or is not to be equivalent BUFA(1). This is symptomatic of a programming error. Make no assumptions as to the original programmer's intent was. Look at the code and verify.

Jim Dempsey

0 Kudos
Steve_Lionel
Honored Contributor III
2,786 Views

My guess is that the original coders didn't compile with bounds checking enabled. It makes me wonder how good the answers are from NASTRAN with errors such as this.

0 Kudos
cryptogram
New Contributor I
2,786 Views

In older code, from back in the days when memory was scarce, it wasn't uncommon to use the same memory for two different things.  The first computer on which I used Fortran had a grand total of 20,000 digits of magnetic core memory.  

The rules of common blocks implicitly make buf(102) and bufa(2) equivalent.  I imagine 3 cases.

1. The programmer really meant to do this (unless it says this somewhere in the comments, unlikely)

2.  It's a mistake, but harmless in this context.  For this to be true, the program would have to be using buf(102) only before bufa(2) was ever

used or only after bufa(2) was used.

3, It's a mistake, and either buf(102) or bufa(2) ends up with incorrect data.

 

0 Kudos
Steve_Lionel
Honored Contributor III
2,786 Views

cryptogram wrote:

The rules of common blocks implicitly make buf(102) and bufa(2) equivalent.  

No they don't, and I have seen examples where the compiler breaks this. It took some time to convince me that the compiler was allowed to do that, but in the end I agreed that it was. COMMON specifies a "sequence of storage units", but there is nothing in the standard promising that each variable in the COMMON directly follows in memory the previous one. 

The standard outright forbids access of array elements outside declared bounds (for each dimension).

0 Kudos
JohnNichols
Valued Contributor III
2,783 Views

Make no assumptions as to the original programmer's intent was. 

So true -- my mum said the same thing many times but usually about my father. 

 

0 Kudos
Bowman__Eric
Novice
2,786 Views

Well, I'm going to try changing all BUF(102) to BUFA(2) and see how that goes, if that wasn't their intent I should get some pretty clear runtime errors once it will compile. 

Also, I have some sample files I can compare results with so if I get different numbers, I'll know where to look. 

On a side note, I have one last problem to solve before this code should compile. It's the same array bound error I was getting with BUF with a twist. 

Here is the offending line of code: 
 

      IF (NBIT .EQ. NS (16)) I = 5

and here it is defined in a common block: 
 

      COMMON /SEM   / DUMMY(3),NS(1)

The odd thing to me is that the 'SEM' common block has different definitions through the application. For example here's one: 

C
C     -------------------     / SEM    /     ---------------------------
C
C     SEM DEFINES DATA FOR THE LINK DRIVERS (XSEMI).
C     MASK   = OSCAR MASK
C     MASK2,MASK3 =  OSCAR MASKS (MACHINE DEPENDENT).
C     NAME   = ARRAY OF LINK NAMES
C
CWKBR COMMON /SEM   / MASK, MASK2, MASK3, NAME(15)
      COMMON /SEM   / MASK, MASK2, MASK3, NAME(30)


 

0 Kudos
Bowman__Eric
Novice
2,786 Views

I'm guessing that since one of the SEM definitions has the final array with a size of 30, that memory is available to any other place that common block is used. So, it looks like I should just change NS(1) to be NS(30)?

0 Kudos
Steve_Lionel
Honored Contributor III
2,786 Views

Whoever wrote this code should be shot. Should it prove inconvenient to shoot him or her, they should be forced to rewrite it correctly. This is NASTRAN, you say?

The Fortran standard explicitly prohibits named COMMON blocks having different lengths in different program units. (This rule does not apply to "blank COMMON".)  On some platforms, this may "work" with the linker using the maximum of all the lengths, but that is not guaranteed. And, of course, with bounds checking enabled, the compiler has to go by what declarations it sees.

In the case you show, a better fix would be to ensure that SEM is (30) in all program units. And yes, changing  NS to NS(30) is a reasonable fix.

0 Kudos
jimdempseyatthecove
Honored Contributor III
2,786 Views

Steve's suggestion in this case is correct... however not stated...

*** Do not assume you can safely enlarge an array size in a common when the offending array is not the last variable/array in the common (all same named commons). Before doing that, examine all the files containing (or including) that named common to assure you do not break the code.

Jim Dempsey

0 Kudos
JohnNichols
Valued Contributor III
2,783 Views

Steve Lionel (Ret.) (Blackbelt) wrote:

Whoever wrote this code should be shot. Should it prove inconvenient to shoot him or her, they should be forced to rewrite it correctly. This is NASTRAN, you say?

The Fortran standard explicitly prohibits named COMMON blocks having different lengths in different program units. (This rule does not apply to "blank COMMON".)  On some platforms, this may "work" with the linker using the maximum of all the lengths, but that is not guaranteed. And, of course, with bounds checking enabled, the compiler has to go by what declarations it sees.

In the case you show, a better fix would be to ensure that SEM is (30) in all program units. And yes, changing  NS to NS(30) is a reasonable fix.

 

Shooting might be a bit strong perhaps a gentle talking to like Max Smart and the 40 scouts

0 Kudos
JohnNichols
Valued Contributor III
2,783 Views

The Fortran standard explicitly prohibits named COMMON blocks having different lengths in different program units. 

------------------------------------------------------------------------------------------------------------------------------------------------------------

Some of the 1968 code from the Powell Dynamic's Group out of UCB used different length commons -- took me a while to sort that out as compilers progressed  - but whoever taught those guys Fortran in 68 did a great job. 

0 Kudos
Bowman__Eric
Novice
2,786 Views

This is NASTRAN taken directly from NASA's GIT repo.

You guys crack me up, it's nice to meet a group of gentleman who are passionate about Fortran :)

I'll probably just start by changing NS(1) to NS(30) but if it doesn't run correctly I'll plan to fix all of the common blocks with the same name.

Eric

0 Kudos
jimdempseyatthecove
Honored Contributor III
2,786 Views

>>I'll probably just start by changing NS(1) to NS(30) but if it doesn't run correctly I'll plan to fix all of the common blocks with the same name

You won't know if it runs correctly by making a few "successful" runs.

"Failure is not always an option"

I've converted a largish project from NASA (750 files) and often is the case where the same named common is mapped differently (names and type differ as well as size). You must be very diligent when making any changes. The programmers that wrote these programs had limited memory to work with, and were very smart at reusing pieces of the common for something else when they knew the lifetime of the former variable had expired. Do not take it for granted that these were programming errors.

Jim Dempsey

0 Kudos
JohnNichols
Valued Contributor III
2,783 Views

Bowman, Eric wrote:

This is NASTRAN taken directly from NASA's GIT repo.

You guys crack me up, it's nice to meet a group of gentleman who are passionate about Fortran :)

I'll probably just start by changing NS(1) to NS(30) but if it doesn't run correctly I'll plan to fix all of the common blocks with the same name.

Eric

If you are looking for gentleman then I suggest you try the TARBOARD - type that in any browser. A wife from this group once described this group of white haired old men sitting around and drinking tea as gentleman.  

This is a group of ladies and dubious characters whose interest in Fortran is possibly Troianas ut bellator.  I often feel Heinlein in one of his famous books describes these "gentleman" well. - Time enough for Love pg 263 - New England Library.  If you have not read it -- one of the most humourous books ever. 

0 Kudos
JohnNichols
Valued Contributor III
2,783 Views

This is NASTRAN taken directly from NASA's GIT repo.

Neil Armstrong can probably give you a lecture on NASA error codes.  

0 Kudos
Reply