Is it possible in modern Fortran to return an array from a function with performance equivalent to having a subroutine fill an array passed as argument?
Consider e.g. as simple example
PROGRAM PRETURN
INTEGER :: C(5)
C = FUNC()
WRITE(*,*) C
CALL SUB(C)
WRITE(*,*) C
CONTAINS
FUNCTION FUNC() RESULT(X)
INTEGER :: X(5)
X = [1,2,3,4,5]
END FUNCTION FUNC
SUBROUTINE SUB(X)
INTEGER :: X(5)
X = [1,2,3,4,5]
END SUBROUTINE SUB
END PROGRAM PRETURN
Here the line C = FUNC()
would copy the values from the function return value, before discarding the returned array from the stack. The subroutine version CALL SUB(C)
would fill C
directly, avoiding the extra coping step and memory usage associated with the temporary array – but making usage in expresions like SUM(FUNC())
impossible.
If however, the compiler implementation chose to allocate all arrays on the heap, the return value could be assigned simply by changing the underlying pointer of C
, resulting in equivalent performance between the two versions.*
Are such optimizations made by common compilers, or is there some other way to get function semantics without the performance overhead?
* It would be more apparent with allocatable arrays, but this would run into compiler-support issues. Intel fortran by default doesn't (re)allocate arrays upon assignment of a different-size array but allows the same effect by using an ALLOCATE(C, SOURCE=FUNC())
statement. Gfortran meanwhile does the automatic allocation on assignment but has a bug that prevents ALLOCATE
statements where the shape is derived from the SOURCE
argument and the fix hasn't been included in binary releases yet.