在混合 C/Fortran 应用程序的上下文中,有没有办法检查编译器是否知道“iso_c_binding”(例如 GCC 4.1.2 不知道,而 4.3.4 知道),如预处理指令或者其他的东西?我不能简单地检查 GCC 的版本,因为我可能会使用其他编译器。
谢谢
在混合 C/Fortran 应用程序的上下文中,有没有办法检查编译器是否知道“iso_c_binding”(例如 GCC 4.1.2 不知道,而 4.3.4 知道),如预处理指令或者其他的东西?我不能简单地检查 GCC 的版本,因为我可能会使用其他编译器。
谢谢
我能想到的唯一两个选择是iso_c_binding
为没有此模块的系统推出您自己的版本(如@HighPerformanceMark 建议的那样)或使用预处理器根据编译器版本有条件地编译部分代码。在这两种情况下,您都必须努力确保您的代码可跨系统移植。正如@HighPerformanceMark 所建议的,您可以复制并粘贴 的开源实现iso_c_binding
,但是对于您将代码移植到的每个新系统,您都必须检查此实现是否正确。
根据您希望代码在不可iso_c_binding
用时的行为方式,我建议使用预处理器方法。您说“我不能简单地检查 GCC 的版本,因为我可能会使用其他编译器”。但是,您的所有选项都需要您自己维护代码以在不同系统上使用,在我看来,预处理器方法需要最少的工作量。
以下代码使用预处理器确定编译器版本,并可用于根据编译器版本是否满足某个最低版本来有条件地编译您的代码。对于gfortran:
如果 GNU Fortran 调用预处理器,
__GFORTRAN__
则定义和__GNUC__
,__GNUC_MINOR__
和__GNUC_PATCHLEVEL__
可用于确定编译器的版本。
在一个文件中,假设precomp.inc
我将包含一些预编译器检查,这些检查确定要在您的代码中包含哪些功能。例如,我会检查编译器版本,如果它支持使用iso_c_binding
模块,我会定义一个预处理器宏HAS_ISO_C_BINDING
(或类似的)。precomp.inc
然后可以将该文件包含在代码的其他部分中。该文件可能类似于:
!> \file precomp.inc
!! Preprocessor feature detection.
#if defined(__GFORTRAN__)
#if __GNUC__ >= 4 && __GNUC_MINOR__ >= 3
#define HAS_ISO_C_BINDING 1
#else
#define HAS_ISO_C_BINDING 0
#endif
#elif defined(__INTEL_COMPILER)
#error "I haven't implemented this yet..."
#else
#error "Compiler not yet supported."
#endif
如果您希望能够在不支持 iso_c_binding 模块的情况下进行编译,则可以将最后一个#else
子句中的错误替换为 。HAS_ISO_C_BINDING=0
您的 Fortran 源代码看起来像
program main
#include 'precomp.h'
#if HAS_ISO_C_BINDING
use iso_c_binding
#endif
implicit none
! Some code...
#if HAS_ISO_C_BINDING
! Code which depends on iso_c_binding
#else
! Fallback code
#end if
! Some more code...
end program main
同样,使用正确的方法取决于如果iso_c_binding
不可用,您希望如何编写代码进行编译。如果您的代码需要在没有此模块的系统上编译,那么@HighPerformanceMark 的答案可能会更好。如果您可以在编译时引发错误,或者如果您有一些后备代码iso_c_binding
不可用,那么我将使用此预处理器方法,因为这只需要为您需要使用的每个新编译器添加一个额外的检查。
这个问题被误导了。实际上,您要问的是配套的 Fortran 处理器(假设它存在)是否支持您的 C 程序要求的 C 互操作性的必要方面。C 互操作性不仅仅是一个内在模块的存在。
例如,F2003 处理器提供一个 ISO_C_BINDING 是完全合法的,它表明几乎所有方面的 C 互操作性都不受支持(C_FLOAT、C_REAL 等常量可能具有负值,表示“不支持”)。
因此,除非您对 C 互操作性的使用非常基本(F2003 处理器必须支持某些方面 - 例如 C_INT、C_LOC、C_F_POINTER 等),否则确定功能的唯一实用方法是:
编译一个明确使用所需实体并测试其值的小型 Fortran 程序(不同的负数解释了 Fortran 处理器不提供支持的原因)。正如其他人所写的那样,编译的成功或失败,以及编译成功后的后续程序输出,可用于配置构建的其他方面。
阅读 Fortran 处理器手册。