Fortran中没有解除数组的标量参数

时间:2011-10-18 10:01:04

标签: fortran overloading fortran90

为什么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

这个问题应该问到为什么数组赋值会将标量值源提升为数组目标;不像数组函数。我希望这只是一个方便的特例。在下面的乞讨上限中感激地收到任何评论。

3 个答案:

答案 0 :(得分:4)

如果希望函数处理定标器和数组参数,请将其声明为“elemental”并使用scaler伪参数。然后它将能够处理缩放器和数组实际参数,包括缩放器表达式。这会满足你的需求吗?

改变:

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

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

答案 1 :(得分:3)

使用显式接口(使用模块过程时自动获得)在Fortran中调用的过程需要TKR(类型,种类,等级)匹配。由于数组与标量不同,更不用说排名不匹配,因此不允许这样做。

如果程序过载会导致歧义吗?

那将是一个问题,是的。

在这种情况下,错误信息可能是另一种方法吗?

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

答案 2 :(得分:0)

我认为对此的答案非常明确。让我们稍微修改一下你的例子:

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指出时,元素就是要走的路。否则,只需确保一个参数与一个参数相匹配。