Fortran 90 在将过程作为参数传递时使用隐式接口调用



我想使用牛顿求解器来求解一些方程。这些方程的某些参数在此过程中正在发生变化。我想将方程作为函数传递给牛顿函数,如下所示:http://faculty.washington.edu/rjl/classes/am583s2013/notes/fortran_newton.html

但是我收到了我不明白的警告。

我列出了一个简化的例子:

    module a
      use b
      ! module parameters:
      implicit none
    contains
      subroutine newton_method(f, fp, x0, x, iters, debug)
        implicit none
        real(kind=8), intent(in) :: x0
        real(kind=8), external :: f, fp
        logical, intent(in) :: debug
        real(kind=8), intent(out) :: x
        integer, intent(out) :: iters
        ! Declare any local variables:
        real(kind=8) :: deltax, fx, fxprime
        integer :: k
        fx = f(x)
        fxprime = fp(x)
        deltax = fx/fxprime
        return
      end subroutine newton_method
    end module a
   module b
     type, public::b_argument
        real(kind = 8)::d
        real(kind = 8)::e
        real(kind = 8)::f
     end type b_argument
     type(b_argument):: b_argu
   contains
     function gx( x )    result(gx_out)
       implicit none
       real(kind = 8)::x
       real(kind = 8)::gx_out
       real(kind = 8)::d, e, f
       d= b_argu%d
       e= b_argu%e
       f= b_argu%f
       gx_out = d * x * x + e * x + f
       return
     end function gx
     function gx_prime( x )  result(gx_prime_out)
       implicit none
       real(kind = 8)::x
       real(kind = 8)::gx_prime_out
       real(kind = 8)::d, e
       d= b_argu%d
       e= b_argu%e
       gx_prime_out = 2 * d * x + e
       return
     end function gx_prime
   end module b
   program c
     use a
     use b
     implicit none
     real(kind = 8):: x, x0
     integer :: iters
     logical :: debug ! set to .true. or .false.
     x0 = 1.0 !guess
     !change argument every time
     b_argu%d = 3
     b_argu%e = 4
     b_argu%f = 5
     call newton_method(gx, gx_prime, x0, x, iters, debug)
   end program c

制作文件:

    f90comp = gfortran
    FFLAGS_DEBUG = -Wall -Wextra -Wimplicit-interface -fPIC -fmax-errors=1 -ggdb -fcheck=all -fbacktrace
    FFLAGS_OPT = -ggdb -O3 -fdefault-real-8 -fdefault-double-8 -ffree-line-length-none -Wuninitialized
    exe_file = c
    objects = a.o 
        b.o 
        c.o 
    mods = a.mod 
        b.mod 
        c.mod
    .PHONY: clean
    $(exe_file): $(objects) 
        @$(f90comp) $(FFLAGS_DEBUG) $(objects) -o $(exe_file)
        @echo "Code is now linking..."
    %.o: %.f90
        $(f90comp) $(FFLAGS_DEBUG) -c $<
    clean:
        @rm -rf $(objects) $(exe_file)
        @rm -rf $(mods)
    debug: FFLAGS_OPT = $(FFLAGS_DEBUG)
    debug: $(exe_file)
    a.o: b.o
    c.o: a.o b.o     

我收到的警告是:

   make
   gfortran -Wall -Wextra -Wimplicit-interface -fPIC -fmax-errors=1 -ggdb -fcheck=all -fbacktrace -c b.f90
   gfortran -Wall -Wextra -Wimplicit-interface -fPIC -fmax-errors=1 -ggdb -fcheck=all -fbacktrace -c a.f90
   a.f90:16:17:
                fx = f(x)
                    1
   Warning: Procedure 'f' called with an implicit interface at (1) [-Wimplicit-interface]
   a.f90:17:22:
                fxprime = fp(x)
                         1
   Warning: Procedure 'fp' called with an implicit interface at (1) [-Wimplicit-interface]
   a.f90:6:61:
              subroutine newton_method(f, fp, x0, x, iters, debug)
                                                                1
   Warning: Unused dummy argument 'debug' at (1) [-Wunused-dummy-argument]
   a.f90:6:54:
              subroutine newton_method(f, fp, x0, x, iters, debug)
                                                         1
   Warning: Dummy argument 'iters' at (1) was declared INTENT(OUT) but was not set [-Wunused-dummy-argument]
   a.f90:15:24:
                integer :: k
                           1
   Warning: Unused variable 'k' declared at (1) [-Wunused-variable]
   a.f90:6:44:
              subroutine newton_method(f, fp, x0, x, iters, debug)
                                               1
   Warning: Unused dummy argument 'x0' at (1) [-Wunused-dummy-argument]
   gfortran -Wall -Wextra -Wimplicit-interface -fPIC -fmax-errors=1 -ggdb -fcheck=all -fbacktrace -c c.f90
   Code is now linking...

那么,为什么ffp调用是隐式的呢?它们是作为参数传入的?它们都是在模块中定义的,所以我不能再使用接口了。

在newton_method中,虚拟参数 f 和 fp 的接口是隐式的。而不是用接口块声明它们,你说的是外部。您正在使用的编译器具有可选的诊断功能,可在您对具有隐式接口的过程进行任何调用时发出警告,这是一件好事。您启用了此警告,编译器完成了它的工作。

解决此问题的解决方法是使用 INTERFACE 或 PROCEDURE(abstract_interface) 来声明 f 和 fp,而不是 EXTERNAL。

相关内容

最新更新