Fortran中没有将标量参数提升到数组



为什么Fortran会在表达式中将标量表达式提升为数组,而不是将其作为过程的参数?特别是,标准机构为什么要做出这个设计决定?是否仅仅是因为含糊不清,程序是否应该过载?在这种情况下,错误消息会是一种替代方法吗?

例如,在下面的代码中,最后一条语句x = foo(7)会产生GFortran错误: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

这个问题应该问为什么数组赋值会将标量值源提升为数组目标;与数组函数不同。不过,我认为这只是一个方便的特例。感谢您在下面的乞求帽中收到的任何评论。

如果您希望函数处理scaler和数组参数,请将其声明为"elemental"并带有scaler伪参数。然后,它将能够处理缩放器和数组的实际参数,包括缩放器表达式。那能满足你的需要吗?

变化:

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

也许他们提供了一种做你想做的事的方法,一种方法就足够了?

使用显式接口(使用模块过程时会自动获得(在Fortran中调用过程需要TKR(类型、种类、秩(匹配。由于数组与标量的类型不同,更不用说秩不匹配了,所以这是不允许的。

是否因为模糊性而应该重载程序

这将是一个问题,是的。

在这种情况下,错误消息会是一种替代方法吗

粉红色的独角兽会存在吗?也许吧,但据我所知,他们没有。IOW,Fortran标准目前要求TKR匹配,因此符合标准的编译器必须强制执行这一要求。如果你想改变这一点,我建议你向标准委员会提出建议。

我认为这个问题的答案非常清楚。让我们稍微修改一下您的示例:

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

在调用foo之后,x应该是什么?

现在,当然,根据它是否是intent(in)变量,您可以拥有参数传递更改的语义,但这是而不是,这将为程序员澄清。

如果函数调用应该以某种方式在数组元素上"分布",那么正如MSB所指出的,elemental就是最好的方法。否则,只需要确保自己的参数与自己的参数相匹配。

最新更新