Question

Why is it that Fortran will promote a scalar expression to an array, in an expression, but not as an argument to a procedure? In particular, why did the standards body make this design decision? Is it solely because of ambiguity, should the procedure be overloaded? Could an error message in that situation be an alternative approach?

For example, In the code below, the last statement, x = foo(7), produces the GFortran error: Error: Rank mismatch in argument 'a' at (1) (1 and 0).

module m

  public :: foo

  contains

  function foo(a) result(b)
    integer, dimension(:)       :: a
    integer, dimension(size(a)) :: b
    b = a+1
  end function foo

end module m

program p

  use m

  integer, dimension(4) :: x
  integer, parameter, dimension(4) :: y = (/1,2,3,4/)

  x = 7
  x = foo(x)
  x = foo(y)
  x = foo(x + 7)
  x = foo(7)

end program p

This question should have asked about why an array assignment will promote a scalar value source to an array target; unlike an array function. I expect that's simply a convenient special case though. Any comments gratefully received in the begging caps below.

Was it helpful?

Solution

If you want the function to handle scaler and array arguments, declare it as "elemental" and with scaler dummy arguments. Then it will be able to handle both scaler and array actual arguments, including scaler expressions. Will that meet your need?

The change:

  elemental function foo(a) result(b)
    integer, intent (in)      :: a
    integer :: b
    b = a+1
  end function foo

Perhaps they provided a way to do what you want, and one way was enough?

OTHER TIPS

Procedure calling in Fortran with explicit interfaces (which you get automatically when using module procedures) requires a TKR (type, kind, rank) match. As an array is a different type than a scalar, not to mention the rank mismatch, this is not allowed.

Is it because of ambiguity should the procedure be overloaded?

That would be a problem, yes.

Could an error message in that situation be an alternative approach?

Could pink unicorns exist? Maybe, but to the best of my knowledge they don't. IOW, the Fortran standard currently requires TKR matching, and thus a standard conforming compiler must enforce this requirement. If you want to change that, I recommend making a proposal to the standards committee.

I would think the answer to this is pretty clear. Let's slightly modify your example:

module m

  public :: foo

  contains

  function foo(a) result(b)
    integer, dimension(:)       :: a
    integer, dimension(size(a)) :: b
    b = a+1
    a(2) = -777     ! new line; modify one element
  end function foo

end module m

program p

  use m

  integer :: x
  integer, dimension(4) :: y 

  x = 7
  y = foo(x)  ! pass a scalar

end program p

what is x supposed to be after the call to foo?

Now, sure, you could have the semantics of argument passing change depending on whether or not it's an intent(in) variable, but that is not something which is going to clarify things for programmers.

If the function call is supposed to 'distribute' somehow over array elements, then as MSB points out, elemental is the way to go. Otherwise, one just makes sure one's arguments match one's parameters.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top