使用错误类型的参数调用外部Fortran函数时会发生什么?

ale*_*der 5 floating-point fortran gfortran

如果文件中没有独立函数(不在模块中),并且您使用单精度调用它,而它需要双精度数:

main.f90:

program main

  call test(1.0)
end program main
Run Code Online (Sandbox Code Playgroud)

test.f90:

subroutine test(a)
    double precision :: a
    print *, "a", a
end subroutine
Run Code Online (Sandbox Code Playgroud)

在这种情况下,编译器如何从单精度到双精度"强制转换"? 使用浮点格式,我希望在转换过程中这些位保持不变,但要追加额外的零.那是:

1 = 0 01111111 00000000000000000000000 in single-precision
Run Code Online (Sandbox Code Playgroud)

我希望最终值为2 ^( - 7):

0 01111111000 0000000000000000000000000000000000000000000000000000 in double precision
Run Code Online (Sandbox Code Playgroud)

令人惊讶的是,使用gfortran 6.4.0,最终值为5.2635442471208903E-315.

fra*_*lus 3

编译器不进行强制转换。你写的不是Fortran。

在主程序中,子程序test有一个隐式接口。本质上,编译器对此一无所知,除了它是一个子例程。您还告诉它它有一个(默认)实参。

在引用子例程时提供正确的参数类型和种类是您的责任,而不是编译器的责任。你失败了,所以你没有兼容的 Fortran 程序。Fortran 编译器不欠你任何东西。

您将观察到的内容取决于 Fortran 处理器的实现细节。该子例程需要一个双精度参数,并且没有理由相信它还有其他任何参数。无论是copy-in/copy-out还是某些地址传递1,内存的解释都不会匹配。在虚拟参数中,除了与实际参数的默认实数对应的字节之外的所有字节都是“垃圾”。

如果您为主程序中的子例程提供显式接口,仍然不会进行强制转换,但编译器会注意到不匹配。同样,即使存在隐式接口,某些编译器(可能具有某些编译标志)也会进行一些检查。


1有关可能的引用传递的详细信息,请参阅用户5713492的评论。