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

Passing zero-sized array to subroutine - best practices

Heinzeller__Dom
Beginner
1,980 Views

Suppose I have an array

real, pointer :: foo(:)

which gets allocated as

allocate(foo(nfoo))

and then passed into a subroutine:

subroutine bar(...,nfoo,...,foo,...)
integer, intent(in) :: nfoo
real, intent(in) :: foo(nfoo) ! OPTION A
! OR
real, dimension(nfoo), intent(in) :: foo ! OPTION B
! OR
real, dimension(:), intent(in) :: foo ! OPTION C

What happens if nfoo == 0 ?

I know that zero-sized arrays are allowed in Fortran and that option A works, according to this conversation: https://software.intel.com/en-us/forums/intel-fortran-compiler-for-linux-and-mac-os-x/topic/606809 

What about option B and C? I am getting different results when compiling the code with optimization turned on (-O2, AVX2) with option C.

Thanks,

Dom

0 Kudos
4 Replies
Juergen_R_R
Valued Contributor II
1,980 Views

I don't know what you do with the array in the subroutine, but option C is the one preferred by me in the code, I think it is called automatic array. Interestingly, you are using a pointer to an array, so you could even change the array in the subroutine though the argument is also intent(in). I would say, the preferred way would be then to use an allocatable and intent(inout).

0 Kudos
Trahan__Samuel
Beginner
1,980 Views

The definition of "Array" in the Fortran 2018 standard explicitly states that an array may have zero size (section 5.4.6 paragraph 1).  The dimension declaration also allows size-zero arrays (section 8.5.8.2 paragraph 3).  The allocate statement accepts any integer expression or pair of integer expressions for a range (section 9.7.1.1 lines R934 and R935).  Ranks of the array in an allocate() statement can have zero size (section 9.7.1.2 paragraph 1).

In other words, A, B, and C are all valid, as are your other declarations and your allocate() statement.

The standard does not answer the following questions:

1. Is it a good idea to have zero-sized arrays?

2. Do all Fortran compilers support zero-sized arrays?

3. Will the code's assumptions be violated by zero-sized arrays?

My guesses are: no, no, probably.

0 Kudos
FortranFan
Honored Contributor III
1,980 Views

Heinzeller, Dom wrote:

subroutine bar(...,nfoo,...,foo,...)
integer, intent(in) :: nfoo
real, intent(in) :: foo(nfoo) ! OPTION A
! OR
real, dimension(nfoo), intent(in) :: foo ! OPTION B
! OR
real, dimension(:), intent(in) :: foo ! OPTION C

What happens if nfoo == 0 ?

I know that zero-sized arrays are allowed in Fortran and that option A works ..

What about option B and C?

Options A and B appear the same, as shown there is only the syntactic difference of foo(nfoo) in A versus the use of the explicit DIMENSION attribute in B.

Option C, which uses the assumed shape array that is much bandied in Fortran, is technically the best.  With it, one does not require the additional dummy argument for the array size, the subprogram being called has the array descriptor so it can figure out the array shape from it.  Assumed-shape feature has been around since Fortran 90, and its implementation should be among the most thoroughly tested and optimized facility in Intel Fortran by now, one would think.  So I don't understand what could be going on with -O2 -AVX2 options.

0 Kudos
mecej4
Honored Contributor III
1,980 Views

With Option C, it is necessary to provide the calling routine with an explicit interface to BAR. If that is not done, there is a mismatch and all kinds of things can happen.

0 Kudos
Reply