为什么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
这个问题应该问到为什么数组赋值会将标量值源提升为数组目标;不像数组函数。我希望这只是一个方便的特例。在下面的乞讨上限中感激地收到任何评论。
答案 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指出时,元素就是要走的路。否则,只需确保一个参数与一个参数相匹配。