Frage

I've got a bit of a headache with regard to passing arrays to functions and/or subroutines. My code looks more or less as follows.

program test
implicit none

integer arraySize
parameter (arraySize = 10)

integer myFunction

integer someValue
integer array1(arraySize,arraySize)
...


...
someValue = myFunction(arraySize,array1)
...

end


integer function myFunction(arraySize,array1)
implicit none

integer arraySize
integer array1(arraySize,arraySize)

...

end

I can get sub-programs of this type to compile, and do my relevant maths on values in the array. This is done with several 4 dimensional arrays, all defined in the same type of way described above.

However, I've got a subroutine where I want to pass 5 of these arrays, and do some maths on the values . I figured I'd try using a common statement to simplify the subroutine statement, instead of having each array as an argument. So I have something like the following:

program test2
implicit none

integer arraySize
parameter (arraySize = 10)

integer array1(arraySize,arraySize)
integer array2(arraySize,arraySize)
integer array3(arraySize,arraySize)
common /myArrays/ array1, array2, array3

...
call arraySum(arraySize)
...

end


subroutine arraySum(arraySize)
implicit none

integer arraySize

integer array1(arraySize,arraySize)
integer array2(arraySize,arraySize)
integer array3(arraySize,arraySize)
common /myArrays/ array1,array2,array3

...

end

I tried compiling, and I get this error

integer array1(arraySize,arraySize)
              1
Error: Variable 'arraysize' at (1) in this context must be constant

I am confused for a number of reasons. Have I misunderstood how to use common statements? Surely if I can pass the size of an array to a sub-program as in my first example, then why would this method make any sort of difference; or do I need to redefine another integer in the subroutine and make this a constant equal to the value of arraySize? Or is it just a quirk of F77, and I should just grit my teeth and pass all 3 arrays over in the subroutine argument?

I apologise for the archaic style of the code, and if I've had any misunderstanding of the principles of Fortran programming (my only prior experience is with C & C++). I'd like to use something newer than F77, but it's not an option currently (student).

War es hilfreich?

Lösung

The summary of the answer is that you can pass the size of the array when and only when the array is a dummy argument in the subprogram.

From the standard:

Each array declarator is either an actual array declarator or a dummy array declarator.

5.1.2.1 Actual Array Declarator.
An actual array declarator is an array declarator in which the array name is not a dummy argument. Each actual array declarator must be a constant array declarator. An actual array declarator is permitted in a [..] COMMON statement

5.1.2.2 Dummy Array Declarator.
A dummy array declarator is an array declarator in which the array name is a dummy argument. A dummy array declarator may be [..] an adjustable array declarator [..]. A dummy array declarator may appear only in a function or subroutine subprogram.

If you want to pass arrays in a common block then you'll need to have the bounds as an integer constant expression. As you say, you can define the array size again in the subprogram. Using a source pre-processor could be one way to help keep things consistent. Or, as @george suggests, using a standard-friendly include statement (just make sure you're using a build system).

That said, I suggest it's better to pass arrays as arguments: when you want to use "dynamic" array approaches things will be tricky enough without having to worry about storage association.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top