In C++ various options are possible to pass arguments to functions (pass by value, reference, pointer, reference to const, pointer to const, ...). I was wondering what the Fortran analogue would be for all these options. This analogue would be from a concept point of view, and not an interoperability point of view.
As far as I know, Fortran passes its arguments by reference, with some exceptions to this rule (non-contiguous arrays). With this in mind, are the following conversions correct, or are there better attributes that can be given?
void f(X x); // Pass by valueThis is a mere copy of the original value that is passed
SUBROUTINE f(x) TYPE(X), VALUE :: x ... END SUBROUTINE fvoid f(X &x); // Pass by referenceHere
xis a reference whose value is updated. As pass by reference is the "default" in Fortran, I see two possible options remaining: the argument anINTENT(OUT)orINTENT(INOUT)SUBROUTINE f(x) TYPE(X), INTENT([IN]OUT) :: x ... END SUBROUTINE fvoid f(X const &x); // Pass by reference-to-constHere
xis a reference whose value cannot be updated.SUBROUTINE f(x) TYPE(X), INTENT(IN) :: x ... END SUBROUTINE fvoid f(X *p); // Pass by pointerThis is a mere copy of a pointer that is passed. However, this would imply that the attributes
POINTERandVALUEshould be combined, but this is not allowed in Fortran. The only alternative I can imagine isSUBROUTINE f(x) TYPE(X), INTENT(INOUT) :: x TYPE(X), POINTER :: p => x ... END SUBROUTINE fvoid f(X const *p); // Pass by pointer-to-constHere
pis a pointer pointing to a const which is copied over. This is, however, the same problem as withf(X *p)SUBROUTINE f(x) TYPE(X), INTENT(IN) :: x TYPE(X), POINTER :: p => x ... END SUBROUTINE fvoid f(X * const p); // Pass by const-pointerHere
pis a pointer that cannot change, but the object it points to can. Againpis a copy and not a referenceSUBROUTINE f(x) TYPE(X), INTENT(INOUT) :: x TYPE(X), POINTER, PARAMETER :: p => x ... END SUBROUTINE fvoid f(X const * const p); // Pass by const-pointerHere
pis a pointer that cannot change and neither can the object it points to. Againpis a copy and not a referenceSUBROUTINE f(x) TYPE(X), INTENT(IN) :: x TYPE(X), POINTER, PARAMETER :: p => x ... END SUBROUTINE fvoid f(X * & p); // Pass by reference-to-pointerThis is a reference to a pointer, both
pand the object it points to can change.SUBROUTINE f(p) TYPE(X), POINTER, INTENT([IN]OUT) :: p ... END SUBROUTINE fvoid f(X const * & p); // Pass by reference-to-pointer-to-constHere
preferences a pointer to a constant object. There seems to be no analogue here.void f(X * const & p); // Pass by reference-to-const-pointerHere
pis a reference to a pointer that cannot change, but the object it points to can.SUBROUTINE f(p) TYPE(X), POINTER, INTENT(IN) :: p ... END SUBROUTINE fvoid f(X const * const & p); // Pass by reference-to-const-pointer-to-constHere
pis a reference to a pointer that cannot change, and neither can the object it points to. Is there an analogue here?