oso*_*maz 10 fortran fortran90
这是以下部分,
调用Fortran 90样式例程的危险
Run Code Online (Sandbox Code Playgroud)program main real, dimension(5) :: x x = 0. ! THIS IS WRONG call incb(x) print *, x end program main subroutine incb(a) ! this is a fortran90 style subroutine real, dimension(:) :: a a = a + 1. end subroutine incb解释子例程incb使用Fortran 90样式的假定形状数组(包含维度(:)).此类例程必须位于模块中,或者在使用它们的任何地方都具有显式接口.在这个例子中,没有一个是真的.
调用此类过程的一种正确方法是使用显式接口,如下所示:
Run Code Online (Sandbox Code Playgroud)program main real, dimension(5) :: x ! THIS IS THE RIGHT WAY interface subroutine incb(a) real, dimension(:) :: a end subroutine incb end interface x = 0. call incb(x) print *, x end program main subroutine incb(a) ! this is a fortran90 style subroutine real, dimension(:) :: a a = a + 1. end subroutine incb如果例程在模块中,则会自动生成接口,并且不需要显式写入.
Run Code Online (Sandbox Code Playgroud)! THIS IS ANOTHER RIGHT WAY module inc contains subroutine incb(a) ! this is a fortran90 style subroutine real, dimension(:) :: a a = a + 1. end subroutine incb end module inc program main use inc real, dimension(5) :: x x = 0. call incb(x) print *, x end program main如果使用接口,接口必须与实际功能匹配.
所以继续我的问题,是否有一个选项gfortran或其他编译器阻止编译,如果有一个程序调用其接口未明确定义(或在模块中定义)?
如果没有,它不应该是一个功能?
对于gfortran,有编译选项-Wimplicit-interface:
-Wimplicit-procedure
如果调用的过程既没有显式接口也没有声明为EXTERNAL,则发出警告.
这可以与-Werror将其视为错误相结合.
编译时(使用gfortran 4.8.2)
call heffalump(1)
end
Run Code Online (Sandbox Code Playgroud)
一看见
call heffalump(1)
1
警告:在(1)处使用隐式接口调用过程'heffalump'
但请注意,尽管这对于新开发的现代代码中的"愚蠢错误"是一个有用的测试,但事情可能非常正确,但仍然无法通过此测试.另见Vladimir F对此答案的评论.
当然,在大多数情况下,编译器无法判断该过程是否需要显式接口.请参阅此答案,了解允许编译器在这方面做一些额外工作的选项.
是的,编译器确实有这个。Ifort 已-warn interfaces包含在-warngfortran 中-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
Run Code Online (Sandbox Code Playgroud)
但是,如果它们驻留在不同的文件中,编译器将在检查这一点时遇到问题。有些人会找到,有些人不会。
> 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)
Run Code Online (Sandbox Code Playgroud)
正如@francesalus 所写,您可以强制对隐式接口发出警告-Wimplicit-interface。然而,这做了一些不同的事情。它警告每个具有隐式接口的过程,即使它是符合标准的。
如果你连接它,-Werror你将不得不为每个使用缓冲区的 MPI 过程编写一个接口,到你使用的每个遗留库。我使用它,但我的代码严格地在模块中,我真的必须为我使用的每个 MPI 过程编写接口,发送或接收一些缓冲区。对于每种类型的缓冲区,您都需要单独的接口(至少在当前的 Fortran 2008 中)。
更糟糕的是,一些 MPI 实现为某些过程提供了显式接口,而有些则没有。一旦您努力为一个 MPI 库版本声明所需的接口,另一个版本就会开始抱怨接口已经定义并且它们不同。(战壕中的真实故事。)