Question

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).

Était-ce utile?

La solution

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.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top