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



考虑代码:

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显式接口
1在过程标识符的范围内,如果不是语句函数,并且

(3(程序有一个(a(具有ALLOCATABLE、ASYNCHRONOUS、OPTIONAL的伪参数,POINTER、TARGET、VALUE或VOLATILE属性

(6(过程具有BIND属性。

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

该标准将显式接口定义为:

3.90.2
显式接口
过程的接口,包括过程的所有特征及其伪参数的名称除了星号伪参数(15.4.2(

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

相关内容

最新更新