Fortran analogue to C++ function arguments

Viewed 470

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 an INTENT(OUT) or INTENT(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 and VALUE should be combined, but this is not allowed in Fortran. The only alternative I can imagine is

    SUBROUTINE 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 with f(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. Again p is a copy and not a reference

    SUBROUTINE 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. Again p is a copy and not a reference

    SUBROUTINE 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?

0 Answers
Related