【问题标题】:Check that iso_c_binding is available at compile-time检查 iso_c_binding 在编译时是否可用
【发布时间】:2012-08-14 15:09:29
【问题描述】:

在混合 C/Fortran 应用程序的上下文中,有没有办法检查编译器是否知道“iso_c_binding”(例如 GCC 4.1.2 不知道,而 4.3.4 知道),就像 pre -处理指令或什么? 我不能简单地检查 GCC 的版本,因为我可能会使用其他编译器。

谢谢

【问题讨论】:

  • 检查#ifdef iso_c_binding等是否有效...
  • 编译一个简单的程序,使用来自ISO_C_BINDING的你需要的东西。如果它编译并运行,您可以将预处理器符号定义附加到某些配置头文件中。将此作为代码构建过程的一部分。这就是 GNU autoconfconfigure 脚本中的做法。
  • 是否可以用 CMake 做类似的事情?
  • @H2CO3:不,它不起作用:(
  • 对不起,CMake 对我来说是黑魔法。可能可以运行一个外部程序(编译测试源 && 运行它)并根据结果设置一个 CMake 变量,例如将-DHAS_ISO_C_BINDING 附加到编译器/预处理器命令行选项。

标签: c preprocessor fortran fortran-iso-c-binding


【解决方案1】:

我能想到的唯一两个选择是为没有此模块 (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 不可用时您有一些后备代码,那么我将使用此预处理器方法,因为这只需要为您需要使用的每个新编译器添加一个额外的检查。

【讨论】:

  • 哇,伙计。我特别不建议复制iso_c_binding 的英特尔 Fortran 源代码,因为这可能侵犯英特尔的知识产权,这可能是非法的,也可能违反我的雇主与英特尔签订的软件供应合同条款。我建议复制该模块的开源实现。我已经编辑了您的问题以删除您的诽谤性断言。
  • 很公平 - 对此表示歉意。
【解决方案2】:

这个问题被误导了。实际上,您要问的是配套的 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 处理器手册。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-10-04
    • 1970-01-01
    • 1970-01-01
    • 2010-12-30
    • 2013-03-16
    • 1970-01-01
    • 2022-01-12
    相关资源
    最近更新 更多