考虑代码:
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
关键字开头的实际代码。