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 value
This is a mere copy of the original value that is passed
SUBROUTINE f(x) TYPE(X), VALUE :: x ... END SUBROUTINE f
void f(X &x); // Pass by reference
Here
x
is 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 f
void f(X const &x); // Pass by reference-to-const
Here
x
is a reference whose value cannot be updated.SUBROUTINE f(x) TYPE(X), INTENT(IN) :: x ... END SUBROUTINE f
void f(X *p); // Pass by pointer
This is a mere copy of a pointer that is passed. However, this would imply that the attributes
POINTER
andVALUE
should 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 f
void f(X const *p); // Pass by pointer-to-const
Here
p
is 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 f
void f(X * const p); // Pass by const-pointer
Here
p
is a pointer that cannot change, but the object it points to can. Againp
is a copy and not a referenceSUBROUTINE f(x) TYPE(X), INTENT(INOUT) :: x TYPE(X), POINTER, PARAMETER :: p => x ... END SUBROUTINE f
void f(X const * const p); // Pass by const-pointer
Here
p
is a pointer that cannot change and neither can the object it points to. Againp
is a copy and not a referenceSUBROUTINE f(x) TYPE(X), INTENT(IN) :: x TYPE(X), POINTER, PARAMETER :: p => x ... END SUBROUTINE f
void f(X * & p); // Pass by reference-to-pointer
This is a reference to a pointer, both
p
and the object it points to can change.SUBROUTINE f(p) TYPE(X), POINTER, INTENT([IN]OUT) :: p ... END SUBROUTINE f
void f(X const * & p); // Pass by reference-to-pointer-to-const
Here
p
references a pointer to a constant object. There seems to be no analogue here.void f(X * const & p); // Pass by reference-to-const-pointer
Here
p
is 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 f
void f(X const * const & p); // Pass by reference-to-const-pointer-to-const
Here
p
is a reference to a pointer that cannot change, and neither can the object it points to. Is there an analogue here?