Aliasing in Fortran function

2019-07-16 23:42发布

问题:

For optimisation reasons, Fortran enforces that the dummy arguments of a subroutine or function are not alias, i.e., they do not point the the same memory place.

I am wondering if the same constraint applies to the returned value of a function. In other words, for a given myfunc function:

function myfunc(a)
    real, intent(in) :: a(:)
    real             :: myfunc(size(a))
    myfunc = a * 2
end function myfunc

is it standard-compliant to write: a = myfunc(a) and b = myfunc(a) ?

回答1:

The arguments of a function and function return value are different things. Contrary the previous answer, the functional arguments ARE passed by reference, or by copy-in copy-out, unless they are declared as dummy arguments with the VALUE attribute. This is a major difference of Fortran vs. C.

However, if the function value is constructed by normal assignment (=) and not by pointer assignment (=>) they are separate entities. In your code, the value of myfunc is got by copying the value of a. Therefore no standard rules are broken by a = myfunc(a) or b = myfunc(a).



回答2:

Since the variable a in myfunc is a separate entity from a that is being passes as a dummy argument from the parent routine, it is perfectly fine to do:

a = myfunc(a)

or

a = SQRT(a)

There is no conflict here because value of a is being copied to the dummy argument inside the function, the function is being evaluated, and in the end the value of the function is being copied to a.

From Fortran 2008 Standard draft:

12.5.3 Function reference

1 A function is invoked during expression evaluation by a function-reference or by a defined operation (7.1.6). When it is invoked, all actual argument expressions are evaluated, then the arguments are associated, and then the function is executed. When execution of the function is complete, the value of the function result is available for use in the expression that caused the function to be invoked. The characteristics of the function result (12.3.3) are determined by the interface of the function. If a reference to an elemental function (12.8) is an elemental reference, all array arguments shall have the same shape.

In general, it is good practice to force functions to not have side-effects, e.g. use PURE attribute and declare INTENT for all dummy arguments.