在文章Fortran 90程序中的错误可能会让您感到惊讶中
下面这一节,
调用Fortran 90样式例程的危险 程序主实,维数(5) ::x= 0。好了!这是错误的调用incb(x)打印*,x结束程序主程序incb(a)!这是一个fortran90样式的子例程--真正的维度(:):a=a+ 1. end子例程incb 解释子例程incb使用Fortran 90样式的假定形状数组(包含维度(:))。这样的例程必须在模块中,或者在任何使用它们的地方都有一个显式接口。在这个例子中,两者都不是真的。 调用这些过程的一种正确方法是使用如下显式接口: 程序主实,尺寸(5) ::X!这是接口子例程incb(a) real,维度(:) ::end子例程incb终端接口x= 0的正确方式。调用incb(x) print *,x端程序主程序incb(a)!这是一个fortran90样式的子例程--真正的维度(:):a=a+ 1. end子例程incb 如果例程位于模块中,则会自动生成接口,不需要显式地编写接口。 好了!这是另一个正确的方式模块公司包含子例程麻管局(A)!这是一个fortran90样式的子例程,维度(:) ::a=a+ 1. end子例程incb终端模块公司程序主要使用inc,维度(5):x= 0。调用incb(x) print *,x end program main 如果使用接口,则该接口必须与实际函数匹配。
因此,继续我的问题,如果调用一个接口未定义(或定义在模块中)的过程,gfortran
或其他编译器中是否有防止编译的选项?
如果不是的话,这难道不应该是一个特色吗?
发布于 2014-05-26 18:07:57
对于gfortran,有一个编译选项-Wimplicit-interface
-隐式-程序 如果调用的过程既没有显式接口,也没有声明为外部的过程,则警告。
这可以与-Werror
相结合,从而将其视为错误。
如何编译(用gfortran 4.8.2)
call heffalump(1)
end
一看
呼叫heffalump(1) 1 警告:在(1)处使用隐式接口调用过程'heffalump‘
但是,请注意,虽然这是对新开发的现代代码中的“愚蠢错误”的有用测试,但事情可能是相当正确的,而且仍然失败。另见弗拉基米尔·F对这一答复的评论。
当然,在大多数情况下,编译器无法判断过程是否需要显式接口。有关允许编译器在这方面做一些额外工作的选项,请参见这个答案。
发布于 2014-05-26 17:56:20
是的,编译器确实有这个。Ifort有-warn interfaces
,包括在-warn
中,gfortran在-Wall
中有这个检查。
interf.f90:6.15:
call incb(x)
1
Error: Procedure 'incb' at (1) with assumed-shape dummy argument 'a' must have an explicit interface
但是,如果编译器驻留在不同的文件中,则在检查这一点时会遇到问题。有些人会找到,有些人不会。
> gfortran incb.f90 interf.f90 -Wall
> ifort incb.f90 interf.f90 -warn
interf.f90(6): error #7978: Required interface for passing assumed shape array is missing from original source [X]
call incb(x)
----------------^
compilation aborted for interf.f90 (code 1)
正如@francesalus所写的,您可以强制对隐式接口-Wimplicit-interface
发出警告。然而,这做了一些不同的事情。它对每一个具有隐式接口的过程发出警告,即使它是符合标准的。
如果您将其与-Werror
连接,则必须为使用缓冲区的每个MPI过程编写一个接口,并将其写入您使用的每个遗留库。我使用它,但我的代码严格地在模块中,我真的必须编写接口到我使用的每一个MPI过程,发送或接收一些缓冲区。对于每种类型的缓冲区,都需要单独的接口(至少在当前的Fortran 2008中是这样)。
更糟糕的是,一些MPI实现为某些过程提供了显式接口,而有些则没有。一旦您为一个MPI库版本声明了所需的接口,另一个就会开始抱怨接口已经定义了,并且它们不同。(来自战壕的真实故事)
https://stackoverflow.com/questions/23873133
复制相似问题