我可以假设 Fortran 预处理器适用于大多数系统吗?

kor*_*rok 1 preprocessor fortran

我正在尝试在 Fortran 中模拟 C 断言,以便强制执行所有过程的前置条件和后置条件。通过这种方式,我可以向用户提供有关运行时错误的更详细的信息,而不是我可以合理预期维护的信息。

为了实现这一点,我使用了预处理器指令__FILE____LINE__,并定义了一个assert扩展为 Fortran 子例程调用的宏。我没有尝试在这里描述它,而是创建了一个git 存储库,其中包含一些示例代码。如果你用它来构建它

make test
./test
Run Code Online (Sandbox Code Playgroud)

该函数挂起,因为您调用的函数需要正参数和负参数。但是,如果您使用

make test DEBUG=1
./test
Run Code Online (Sandbox Code Playgroud)

错误被断言捕获。

这适用于 gfortran 和 Intel Fortran 编译器。我无法访问其他 Fortran 编译器。如果文件扩展名是 ,我可以合理地期望其他编译器进行必要的源预处理吗.F90?或者我应该依靠旗帜-cpp?最便携的方法是什么?我到底应该这样做吗?

Ian*_*anH 5

尽管某些编译器或工具无疑会有例外,但可以合理地期望有合适的“类 C”预处理器可用。

可移植性的定义可能取决于您的观点,但考虑到大量系统运行不区分大小写的文件系统,仅依靠大小写来指定需要运行预处理器是不合理的。大多数与 Fortran 相关的构建系统都会有某种方式使该规范变得明确。

这是否是一个好主意有点主观。也许就影响而言,这只是名义上的,但需要预处理器仍然意味着可移植性的降低和构建复杂性的增加。根据编译器的不同,预处理器的使用可能会妨碍标准一致性诊断等功能的使用。

因此,我对像这样相对简单的用例的偏好是将断言编码为正常的 Fortran 源代码 - if 语句测试来自调试模块或类似模块的命名常量,exit如果断言表达式失败。

USE DebuggingFlags

IF (debug_flag) THEN
  IF (x <= 0) ERROR STOP 'negative or zero x in sqrrt!'
END IF
Run Code Online (Sandbox Code Playgroud)

这不会为您提供文件和行信息,但只要您对 STOP 消息有一定的选择性,相关源就不难找到。

“发布”构建是使用定义为 false(或您选择的等效项)的调试标志常量进行的,并且通过任何类型的合理的编译器优化活动,与断言相关的目标代码应该被识别并消除为死的。

但有利有弊。