我能想到的唯一两个选择是为没有此模块 (as suggested by @HighPerformanceMark) 的系统推出您自己的 iso_c_binding 版本,或者使用预处理器有条件地编译部分代码,具体取决于编译器版本。在这两种情况下,您都必须努力确保您的代码可跨系统移植。正如@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 不可用时您有一些后备代码,那么我将使用此预处理器方法,因为这只需要为您需要使用的每个新编译器添加一个额外的检查。