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

passing array to subroutine with common declaring array to have length 1

ester_maria_v_
Beginner
972 Views

 Dear Developers,

I'm new in fortran programming and I found something that I can't understand clearly. I'm working with a complex code which uses a lot of subroutines in which array are passed by using the common declaration with the array size equal to 1. In the following I propose to you a simple example of what appened in this code:

      program COMMON_test
      parameter (MAX=5)
      COMMON/A1/A(MAX)
      DATA A(1),A(2),A(3),A(4),A(max)/1,1,1,1,1/
      CALL SUB
       end 
      
      subroutine SUB
      Parameter (MAX=5)
      COMMON/A1/A(1)
      DO I=2,MAX
          A(I)=A(I-1)+1
      END DO
      RETURN    
      END

This code run only if I deselect the "check array and string bounds". I tried to study what happened running the code line by line (with visual studio) and what I could understand is that in the subroutine SUB, A is not viewed as an array, in fact visual studio shows that it has only one element, but its actual elements, I mean A(2), A(3), A(4) and A(5), are modified by the subroutine instead.

I would appreciate if someone could explain me how this is possible.

Thanks very much for the attention

Ester

0 Kudos
3 Replies
mecej4
Honored Contributor III
972 Views

The code of your complex project was probably debugged and in working order but not intended to be subject to the torture of subscript checking. Many older codes do fit that description.

Unless special steps are taken, a Fortran compiler compiles each subprogram separately, and without using any information from other sources (other than INCLUDEd parts of code). Therefore, let us consider just the lines of source In the subroutine. The array is declared to be of dimension 1. When this code is compiled, there is no presumption that the common block is also declared somewhere else, and with a bigger size. Clearly, the array bound is exceeded even in the first iteration of the DO loop.

Subroutines that are intended to work on vectors and matrices of various sizes should not be written with the vector/matrix dimensions in a common block. Instead, the dimensions cab be passed as additional arguments or by using assumed shape arguments.

Will Rogers could have said that subscript checking is a tool for turning successful old Fortran code into a program that is guaranteed to fail. It does more harm than good to turn subscript checking on for many fine programs written in the 1960s and 1970s (some people still continue to write in Fortran IV, so this comment applies to their output, as well).

0 Kudos
andrew_4619
Honored Contributor III
972 Views

COMMON/A1/A(1) 

The common block has a memory address and the compiler has been told that in SUB there is an real (by default on its initial name letter) array starting at that address. The compiler does not know how big the array is, (1) is a special case used in old code to just specify it as an array of unknown size. The elements of the array are in sequential memory locations from the start address. It is down to the programmer not to exceed the array bounds and cause memory corruption.

There are much better ways to do this in modern code but there is a great deal of old code that does things this way....

 

0 Kudos
ester_maria_v_
Beginner
972 Views

Thank you both for the useful information

Ester

0 Kudos
Reply