下面的MWE描述了我想使用的内容(请注意,我没有设计它,我只是尝试使用某人的代码,通常不使用全局变量)。
PROGRAM MAIN
IMPLICIT NONE
integer :: N
real(8), allocatable :: a(:,:)
N=3
allocate(a(N,3))
a=initialize_array()
CONTAINS
function initialize_array() result(a)
IMPLICIT NONE
real(8) :: a(N,3)
a=1
end function initialize_array
END PROGRAM MAIN
gfortran给出一个错误,该错误表示为Error: Variable 'n' cannot appear in the expression at (1)
,指向real(8) :: a(N,3)
函数内部。在子例程中它将起作用,那么这里可能是什么问题?
为什么ifort(v。15.0.3)会编译它,而gfortran(v。4.8.4)却不能编译?
正如其他人所评论的那样,很难说是否明确允许某些内容:该语言主要基于规则和限制条件。
因此,我不会证明代码不是错误的(并且不允许gfortran拒绝它),但是让我们看看发生了什么。
首先,我将反对高性能标记给出的一件事,因为这有点相关:
要声明尺寸取决于变量值(例如)的数组
a(N,3)
,要求在编译时知道(或至少知道)变量的值。
显式形状数组的边界不一定总是由常量表达式给出(我们将其宽松地定义为“在编译时已知/已知”):在某些情况下,显式形状数组可以具有变量给定的边界。这些被称为自动对象(以及规范表达式所给定的界限)。
函数结果就是这样一个允许自动对象的地方。在问题的示例中用于函数结果的声明,与N
主机关联并形成规范表达式。
a
让我们看看gfortran如何响应程序的少量修改,而不是用所有其他约束来查看是否允许true声明。
首先,是gfortran对象所针对的问题代码的精简版。
integer n
contains
function f() result(g)
real g(n)
end function f
end program
对于函数的结果f
有名字g
。调用函数结果并不重要,那么调用它会发生什么f
呢?
integer n
contains
function f()
real f(n)
end function f
end program
这对我来说很愉快。
如果我们将第一个块放入框架而不是主程序中怎么办?
module mod
integer n
contains
function f() result(g)
real g(n)
end function f
end module
那也可以编译。
自然的结论是:即使gfortran正确(我们错过了一些隐蔽的约束)拒绝第一个代码,也不拒绝其他代码还是非常不一致的,或者约束确实很奇怪。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句