为什么这里需要接口才能获得正确的结果

Why is interface required here for correct results

考虑代码:

subroutine func(i) bind(c)
  use, intrinsic :: ISO_C_BINDING, only: c_float
  implicit none
  real(c_float), value :: i
  print *, i, "+", i, "=", i + i
end subroutine

program main
  use, intrinsic :: ISO_C_BINDING, only: c_float
  implicit none
  real(c_float) :: i = 1.0
  call func(i)
end program

显示5.61379690E-30 + 5.61379690E-30 = 1.12275938E-29,当然是错误的。只有当我添加一个显式接口时,它才会输出正确的结果:

subroutine func(i) bind(c)
  use, intrinsic :: ISO_C_BINDING, only: c_float
  implicit none
  real(c_float), value :: i
  print *, i, "+", i, "=", i + i
end subroutine

program main
  implicit none
  interface
    subroutine func(i)
      real, value :: i
    end subroutine func
  end interface
  real :: i = 1.0
  call func(i)
end program

然后我得到 1.00000000 + 1.00000000 = 2.00000000 这是正确的。

但是是什么导致了这里的错误?为什么需要一个不添加任何新信息的额外接口?

我使用 gfortran,GCC,版本 7.4.0

每个具有 value 伪参数的函数或子例程都需要一个显式接口。这同样适用于具有 bind() 属性的过程。否则调用代码不知道如何正确调用。

Fortran 2018 草案指出:

15.4.2.2 Explicit interface
1 Within the scope of a procedure identifier, the procedure shall have an explicit interface if it is not a statement function and
...
(3) the procedure has a dummy argument that (a) has the ALLOCATABLE, ASYNCHRONOUS, OPTIONAL, POINTER, TARGET, VALUE, or VOLATILE attribute, ...
...
(6) the procedure has the BIND attribute.

请注意,explicit interface 与您使用的 interface 块不同。接口块是提供显式接口的可能方式之一。更好的选择通常是使用模块,有时使用内部过程。

标准将显式接口定义为:

3.90.2
explicit interface
interface of a procedure that includes all the characteristics of the procedure and names for its dummy arguments except for asterisk dummy arguments (15.4.2)

这与 interface 块不同,它是以 interface 关键字开头的实际代码段。