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

时间:2017-11-02 18:41:12

标签: fortran newtons-method

我想使用牛顿求解器来求解一些方程式。这些方程的一些参数在此过程中正在发生变化。我希望将等式作为函数传递给牛顿函数,如下所示: 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调用是隐含的?它们作为参数传递?它们都在模块中定义,所以我不能再使用接口了。

1 个答案:

答案 0 :(得分:3)

在newton_method中,伪参数f和fp的接口是隐式的。你说EXTERNAL,而不是用INTERFACE块声明它们。你正在使用的编译器有一个可选的诊断功能,当你用一个带有隐式接口的程序进行任何调用时警告你,这是一件好事。您启用了此警告,编译器完成了它的工作。

对此的修复是使用INTERFACE或PROCEDURE(abstract_interface)来声明f和fp而不是EXTERNAL。