我试图在Fortran中模拟C断言,以强制执行我所有程序的前后条件。通过这种方式,我可以向用户提供有关运行时错误的更详细信息,而不是我可以合理地预期维护错误。
为了实现这一点,我使用了预处理器指令__FILE__
和__LINE__
,并定义了一个扩展到Fortran子例程调用的assert
宏。我没有尝试在这里描述它,而是在其中添加了一些示例代码git repo。如果你用
make test
./test
函数挂起,因为你调用的函数需要一个带负数的正参数。但是,如果使用
构建make test DEBUG=1
./test
错误被断言捕获。
这适用于gfortran和英特尔Fortran编译器。我无法访问其他Fortran编译器。如果文件扩展名为.F90
,我是否可以合理地期望其他编译器进行必要的源预处理?或者我应该依靠-cpp
旗帜?什么是最便携的方式?我甚至可以这样做吗?
答案 0 :(得分:4)
有理由期待合适的" C-like"预处理器是可用的,但毫无疑问,某些编译器或工具会有例外。
可移植性的定义可能取决于您的观点,但鉴于大量系统使用不区分大小写的文件系统运行,单独依赖案例来指定需要运行预处理器是不合理的。大多数Fortran相关的构建系统都有一些方法可以使该规范明确。
这是否是一个好主意是更主观的。也许它只是名义上的影响,但要求预处理器仍然代表了可移植性的降低和构建复杂性的增加。根据编译器的不同,使用预处理器可能会妨碍使用标准一致性诊断等功能。
因此,我对这种相对简单的用例的偏好是将断言编码为普通的Fortran源 - 一个if语句测试来自调试模块或类似的命名常量,调用[ERROR] STOP(不是{{1}如果断言表达式失败,则使用描述性消息。
exit
这不会给你提供文件和行信息,但只要你对STOP信息有所选择,相关的信息源就不会太难找到。
"推出"使用定义为false(或您选择的等效项)的调试标志常量进行构建,并且在任何类型的合理编译器优化激活时,应该识别与断言相关联的目标代码并将其作为死区消除。
但是有利有弊。
答案 1 :(得分:0)
Fortran 95+在标准中定义了条件编译(coco),但只有少数编译器支持它。 事实上标准(因为我相信Fortran 90)仍然是cpp和fpp,这是大多数编译器所支持的。两者都是highly compatible but not 100%。使用这些事实,依赖于cpp / fpp样式的预处理器对于大多数情况应该是安全的。
答案 2 :(得分:0)
添加@LeleDumbo的答案:
据我所知,Fortran 2008 Standard没有指定任何形式的预处理。这也意味着,没有标准的方法来指定,如何调用预处理器。但是,通常的做法是使用.F90
来指定预处理的需要。
关于COCO:Fortran标准ISO 1539-3的第三部分(应指定条件编译)被撤回。