检查iso_c_binding在编译时是否可用

sun*_*mat 5 c preprocessor fortran fortran-iso-c-binding

在混合C/Fortran应用程序的上下文中,有没有办法检查编译器是否知道"iso_c_binding"(例如GCC 4.1.2不知道它,而4.3.4确实如此),就像预处理指令一样或者其他的东西?我不能简单地检查GCC的版本,因为我可能会使用其他编译器.

谢谢

Chr*_*ris 2

我能想到的唯一的两个选择是为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
Run Code Online (Sandbox Code Playgroud)

如果您希望能够在不支持 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
Run Code Online (Sandbox Code Playgroud)

同样,正确的使用方法取决于您想要如何编码来编译(如果iso_c_binding不可用)。如果您的代码需要在没有此模块的系统上进行编译,那么@HighPerformanceMark 的答案可能会更好。如果您可以在编译时引发错误,或者如果您有一些后备代码iso_c_binding不可用,那么我将使用此预处理器方法,因为这只需要为您需要使用的每个新编译器添加一项额外的检查。