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
Compiler construction gfortran编译器错误?_Compiler Construction_Fortran_Gfortran - Fatal编程技术网

Compiler construction gfortran编译器错误?

Compiler construction gfortran编译器错误?,compiler-construction,fortran,gfortran,Compiler Construction,Fortran,Gfortran,我在一个环境中工作,在这个环境中,我们有一个用于fortran代码的自定义预处理器。我使用预处理器来切换逻辑参数,就像穷人的函数指针一样。我今天意识到我有一个类似的情况: program main logical,parameter :: untrue=.false. if(untrue)then call func1() else call func2() endif end subroutine func2() print*,"Hello,

我在一个环境中工作,在这个环境中,我们有一个用于fortran代码的自定义预处理器。我使用预处理器来切换逻辑参数,就像穷人的函数指针一样。我今天意识到我有一个类似的情况:

  program main
  logical,parameter :: untrue=.false.
  if(untrue)then
    call func1()
  else
    call func2()
  endif
  end

  subroutine func2()
  print*,"Hello, World!"
  end
换句话说,
func1
在任何地方都没有定义,但它使用gfortran(版本4.4和4.6)编译,因为编译器可能会优化调用。我目前没有其他编译器可供检查,这段代码是否在其他地方编译?这是否可以/应该被视为编译器错误


我切换逻辑开关(而不是包括/不包括代码)的部分原因是,编译器仍然可以检查代码块中的接口/语法(如果有能力)(并对不简单的函数调用发出适当的警告)。这是否意味着没有执行这些测试,或者只是链接器不需要该函数,所以一切正常?

这不是编译器错误。缺少引用的外部子程序并不是标准要求Fortran处理器来诊断的问题。其他处理者可能会抱怨,也可能不会抱怨。优化设置之类的事情可能会影响结果-英特尔Fortran 12.1.5抱怨优化关闭,而不抱怨优化打开


对于示例代码,其中func2是一个外部子程序,Fortran对程序单元的单独编译模型意味着不需要进行过程接口检查。对于许多处理器,这种情况不太可能发生(实际上,func2可能在主程序之后很久才编译的单独文件中,可能在另一台机器上,可能在主程序的源代码不再可用的情况下)。如果您想要保证过程接口检查,那么您需要确保过程有一个明确的接口,比如说将它们放在一个模块中。Fortran 2003标准中引入的过程指针语言功能(至少由gfortran 4.6支持)也可能有所帮助。

这里看到的只是编译器允许自己忽略任何永远不会被调用的引用。该行:

logical,parameter :: untrue=.false.
保证不会执行
if
块的第一部分。正如IanH指出的(+1),这不是编译器错误,而是优化过程的一部分。此代码还将使用
pgf90 10.6-0
ifort 12.0.2.137
进行默认优化编译。但是,如果指令在未启用优化的情况下编译,它们将失败

但是如果你的台词是:

logical :: untrue=.false.
编译器更有可能抱怨,因为允许变量
不真实
更改其值。例如,
pgf90
将失败,除非需要更高的优化级别,而“ifort”仍将在默认优化级别上编译


在任何情况下,依赖于编译器行为都不是最佳实践,正如IanH指出的,最好通过使用模块来指定外部函数和子例程接口

这似乎是GNU Fortran特有的行为,即使在优化级别
O0
也会删除无法访问的代码部分。这与ISO/IEC 1539:1991一致:§8.1.2规定必须执行
IF
构造的一个块,并且§8.1.1.2明确禁止将控制权从块外部转移到块内部。这允许编译器删除肯定不会执行的代码部分,这是有意义的,因为在您的示例中,如果不重新编译程序源代码,就无法更改
IF
构造的行为,并且编译器只是精通符号


但我仍然觉得奇怪的是,
gfortran
即使在使用
-Wall-Wunreachable代码编译时也没有警告无法访问的代码,谢谢。在这一点上,我不能依赖标准的更新版本。该代码是15年前编写的,按照预处理器的方式,许多f90结构甚至可能导致其崩溃:-(.我也知道过程检查需要一个接口——但同样,我们的预处理器不支持这个接口。我想,既然这个标准甚至没有解决死代码的问题,任何事情都可以……谢谢。(我会等待一段时间,以确保没有其他人对此有任何意见,如果他们没有,我会很乐意接受这一点。+1是一个很好的答案。
ifort
的默认优化级别是
O2
:)