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

时间:2018-07-09 18:59:26

标签: floating-point fortran gfortran

如果文件中(而不是模块中)具有独立的函数,并且以单精度调用它,而它期望双精度数:

main.f90:

program main

  call test(1.0)
end program main

test.f90:

subroutine test(a)
    double precision :: a
    print *, "a", a
end subroutine

在这种情况下,编译器如何从单精度“转换”为双精度? 使用浮点格式,我希望这些位在强制转换期间保持不变,但会附加附加零。那就是:

1 = 0 01111111 00000000000000000000000 in single-precision

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

0 01111111000 0000000000000000000000000000000000000000000000000000 in double precision

令人惊讶的是,对于gfortran 6.4.0,最终值为5.2635442471208903E-315。

2 个答案:

答案 0 :(得分:3)

编译器不强制转换。您写的不是Fortran。

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

在引用子例程时提供正确的类型和类型的参数是您的责任,而不是编译器的责任。您在此处失败,因此没有兼容的Fortran程序。 Fortran编译器不欠您任何费用。

您将观察到的内容将取决于Fortran处理器的实现细节。该子例程需要一个双精度参数,并且没有理由相信它还有其他内容。不管有复制/复制输出还是某些地址通过 1 ,内存的解释都将不匹配。在哑元参数中,除与实际参数的默认实数对应的字节以外的所有字节均为“垃圾”。

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


1 有关可能通过引用的详细信息,请参见user5713492的注释。

答案 1 :(得分:-2)

我猜编译器会根据字节顺序“广播”。如果您在左侧插入零,则会得到:

0 00000000000 0000000000000000000000111111100000000000000000000000

哪个是5.2635442471208903E-315。您可以在编译时通过强制字节序进行检查。