使用错误类型的参数调用外部 Fortran 函数时会发生什么?
What happens when calling external an Fortran function with the wrong type of arguments?
如果您在文件中(而不是在模块中)有一个独立的函数,并且您使用单精度调用它,而它需要一个双精度数:
main.f90 :
program main
call test(1.0)
end program main
test.f90:
subroutine test(a)
double precision :: a
print *, "a", a
end subroutine
在这种情况下,编译器"casts"如何从单精度到双精度?
使用浮点格式,我希望这些位在转换期间保持不变,但会附加额外的零。即:
1 = 0 01111111 00000000000000000000000 in single-precision
我希望最终值为 2^(-7):
0 01111111000 0000000000000000000000000000000000000000000000000000 in double precision
令人惊讶的是,对于 gfortran 6.4.0,最终值为 5.2635442471208903E-315。
我猜编译器 "casts" 根据字节顺序。如果你在左边放零,你会得到:
0 00000000000 0000000000000000000000111111100000000000000000000000
即 5.2635442471208903E-315。您可以通过在编译时强制字节顺序来检查。
编译器不进行转换。你写的不是Fortran.
在主程序中,子例程test
有一个隐式接口。本质上,编译器对此一无所知,只知道它是一个子程序。您还告诉它它有一个(默认的)真实参数。
在引用子例程时提供正确的参数类型和种类是您的责任,而不是编译器的责任。你在那里失败了,所以你没有兼容的 Fortran 程序。 Fortran 编译器不欠你什么。
您将观察到的内容取决于 Fortran 处理器的实现细节。该子例程需要一个双精度参数,并且没有理由相信它有任何其他参数。不管是有copy-in/copy-out还是某些地址传1,内存的解释都会不匹配。在伪参数中,除了与实际参数的默认实数对应的字节外,所有字节都是 "junk".
如果您在主程序中为子例程提供显式接口,仍然不会进行转换,但编译器会注意到不匹配。同样,即使存在隐式接口,某些编译器(可能具有某些编译标志)也会进行一些检查。
1 有关可能的传递引用的详细信息,请参阅 user5713492 的评论。
如果您在文件中(而不是在模块中)有一个独立的函数,并且您使用单精度调用它,而它需要一个双精度数:
main.f90 :
program main
call test(1.0)
end program main
test.f90:
subroutine test(a)
double precision :: a
print *, "a", a
end subroutine
在这种情况下,编译器"casts"如何从单精度到双精度? 使用浮点格式,我希望这些位在转换期间保持不变,但会附加额外的零。即:
1 = 0 01111111 00000000000000000000000 in single-precision
我希望最终值为 2^(-7):
0 01111111000 0000000000000000000000000000000000000000000000000000 in double precision
令人惊讶的是,对于 gfortran 6.4.0,最终值为 5.2635442471208903E-315。
我猜编译器 "casts" 根据字节顺序。如果你在左边放零,你会得到:
0 00000000000 0000000000000000000000111111100000000000000000000000
即 5.2635442471208903E-315。您可以通过在编译时强制字节顺序来检查。
编译器不进行转换。你写的不是Fortran.
在主程序中,子例程test
有一个隐式接口。本质上,编译器对此一无所知,只知道它是一个子程序。您还告诉它它有一个(默认的)真实参数。
在引用子例程时提供正确的参数类型和种类是您的责任,而不是编译器的责任。你在那里失败了,所以你没有兼容的 Fortran 程序。 Fortran 编译器不欠你什么。
您将观察到的内容取决于 Fortran 处理器的实现细节。该子例程需要一个双精度参数,并且没有理由相信它有任何其他参数。不管是有copy-in/copy-out还是某些地址传1,内存的解释都会不匹配。在伪参数中,除了与实际参数的默认实数对应的字节外,所有字节都是 "junk".
如果您在主程序中为子例程提供显式接口,仍然不会进行转换,但编译器会注意到不匹配。同样,即使存在隐式接口,某些编译器(可能具有某些编译标志)也会进行一些检查。
1 有关可能的传递引用的详细信息,请参阅 user5713492 的评论。