如果未明确定义任何过程接口,或者在Fortran 90+中的模块中,则抛出错误

oso*_*maz 10 fortran fortran90

在文章错误的Fortran 90程序可能会让你感到惊讶

这是以下部分,

调用Fortran 90样式例程的危险

      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
Run Code Online (Sandbox Code Playgroud)

解释子例程incb使用Fortran 90样式的假定形状数组(包含维度(:)).此类例程必须位于模块中,或者在使用它们的任何地方都具有显式接口.在这个例子中,没有一个是真的.

调用此类过程的一种正确方法是使用显式接口,如下所示:

      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
Run Code Online (Sandbox Code Playgroud)

如果使用接口,接口必须与实际功能匹配.

所以继续我的问题,是否有一个选项gfortran或其他编译器阻止编译,如果有一个程序调用其接口未明确定义(或在模块中定义)?

如果没有,它不应该是一个功能?

fra*_*lus 6

对于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对此答案的评论.

当然,在大多数情况下,编译器无法判断该过程是否需要显式接口.请参阅此答案,了解允许编译器在这方面做一些额外工作的选项.


Vla*_*r F 5

是的,编译器确实有这个。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 库版本声明所需的接口,另一个版本就会开始抱怨接口已经定义并且它们不同。(战壕中的真实故事。)