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

Floating point 使用错误类型的参数调用外部Fortran函数时会发生什么情况?,floating-point,fortran,gfortran,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 在这种情况下,编译器如何从单精度“强制转换”到双精度? 使用浮点格式,我希望位在强制转换期间保持不变,但附加

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

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):

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

我猜编译器是根据endianess“强制转换”的。如果你在左边标上零,你会得到:

0 00000000000 0000000000000000000000111111100000000000000000000000

这是5.2635442471208903E-315。您可以在编译时强制endianess进行检查。

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

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

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

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

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



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

无法保证将读取的额外字节都是零;它应该是来自随机内存位置的“垃圾”数据。即使垃圾数据被读取,也无法保证。这是错误的。任何事情都可能发生,包括鼻守护进程。很高兴您能在我的答案中添加这些细节。我也可以这么做,但如果你在署名上抄袭的话就清楚多了。不管怎样:谢谢你的更正。
0 00000000000 0000000000000000000000111111100000000000000000000000