Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
gfortran和ifort(可分配数组和全局变量)之间的编译器差异 代码_Fortran_Gfortran_Intel Fortran - Fatal编程技术网

gfortran和ifort(可分配数组和全局变量)之间的编译器差异 代码

gfortran和ifort(可分配数组和全局变量)之间的编译器差异 代码,fortran,gfortran,intel-fortran,Fortran,Gfortran,Intel Fortran,下面的MWE描述了我想要使用的东西(请注意,我没有设计这个,我只是尝试使用一些人的代码,我通常不会使用全局变量) 问题 gfortran给出了一个错误,该错误读取错误:变量'n'不能出现在表达式中的(1),指向函数中的实数(8)::a(n,3)。 在一个子程序中,它会工作,那么这里可能有什么问题 问题 为什么ifort(15.0.3版)编译了这个,而gfortran(4.8.4版)没有编译呢?我认为这可能是一个解释,尽管像@VladimirF一样,我实际上无法回忆或找到标准的相关部分(如果有)

下面的MWE描述了我想要使用的东西(请注意,我没有设计这个,我只是尝试使用一些人的代码,我通常不会使用全局变量)

问题 gfortran给出了一个错误,该错误读取
错误:变量'n'不能出现在表达式中的(1)
,指向函数中的
实数(8)::a(n,3)
。 在一个子程序中,它会工作,那么这里可能有什么问题

问题
为什么ifort(15.0.3版)编译了这个,而gfortran(4.8.4版)没有编译呢?

我认为这可能是一个解释,尽管像@VladimirF一样,我实际上无法回忆或找到标准的相关部分(如果有)

这条线

real(8) :: a(N,3)
声明函数的结果是一个名为
a
的数组。这掩盖了主机关联引用数组
a
的相同名称的可能性。功能范围内的
a
不是程序范围内的
a

声明维度依赖于变量值的数组,例如
a(N,3)
,要求在编译时变量的值是已知的(或至少是已知的)。在这种情况下,在主机作用域中指定属性
参数
可以解决问题。虽然这并不能解决糟糕的设计问题,但OP似乎在这一点上束手无策

英特尔编译器编译这个并不奇怪,它编译了它的祖先多年来为了向后兼容而编译的各种奇怪的东西


我只提供了这个半生不熟的解释,因为经验告诉我,一旦我这样做,一位真正的Fortran专家(伊恩,弗朗西斯卡勒斯,(通常是)弗拉基米尔)会非常愤怒,以至于发布更正,我们都会学到一些东西。

正如其他人所评论的那样,很难说某些东西是否被明确允许:这种语言主要是基于规则和限制来进行限制的

因此,我不会证明代码没有错误(并且不允许gfortran拒绝它),但让我们看看发生了什么

首先,我将反对由给出的一件事,因为这稍微相关:

声明维度依赖于变量值的数组,例如
a(N,3)
,要求在编译时变量的值是已知的(或至少是已知的)

显式形状数组的边界不一定总是由常量表达式给出(我们松散地定义为“编译时已知/可知”):在某些情况下,显式形状数组可以由变量给出边界。这些对象称为自动对象(以及规范表达式给出的边界)

函数结果就是允许自动对象的地方。在函数结果声明的问题示例中,
N
与主机关联并形成规范表达式

与其穷尽所有其他约束以确保
a
的声明确实被允许,不如让我们看看gfortran如何响应程序的小修改

首先,gfortran对象的问题代码的精简版本

  integer n
contains
  function f() result(g)
     real g(n)
  end function f
end program
f
的函数结果的名称为
g
。无论我们如何调用函数结果,当我们调用它时会发生什么

  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拒绝第一个代码是正确的(我们忽略了一些隐藏得很好的约束),它要么在不拒绝其他代码方面存在严重的不一致性,要么约束非常奇怪。

Solaris Studio也接受这一点。我在标准中找不到任何禁止这样做的东西,但人们可能总是忽略了一些东西。可能值得向gfortran开发人员展示。很难确认标准中是否允许某些内容。通常情况下,我们必须确认没有任何东西禁止这样做,但搜索这样的案例是困难的。我几天前在comp.lang.fortran上问过这一问题,Steve Kargl(gfortran开发者)同意这是一个gfortran bug。我只是没有时间写一份报告。
module mod
  integer n
contains
  function f() result(g)
     real g(n)
  end function f
end module