力学 Fortran 预处理器
Posted
技术标签:
【中文标题】力学 Fortran 预处理器【英文标题】:Mechanics Fortran Preprocessor 【发布时间】:2014-11-13 02:13:39 【问题描述】:我最近碰巧遇到了当今大多数 Fortran 编译器支持的预处理选项(如 Fortran Wiki 中所述)。来自 C 背景,我想更好地了解与 (Fortran-) 预处理器的 #include
指令相关的机制和注意事项。
从一开始就避免任何混淆:Fortran 中有两个 include
指令(参见例如 F77 reference)
include "foo"
是编译器指令,即 foo 只能包含 Fortran 语句
#include "bar"
是一个预处理指令,即 bar 可以包含 #defines
等
我知道这种差异,我只对第二种情况感兴趣(因此我的问题不是this post 的重复)。
我将用一个例子来解释我的问题:假设我们有两个文件,一个头文件 (macro.h) 和一个源文件 (display.F):
宏.h
#define MSG() say_hello()
display.F
#include "macro.h"
PROGRAM display
CALL MSG()
CALL another_message()
END
SUBROUTINE say_hello()
WRITE(*,*) 'Hello.'
END
SUBROUTINE another_message()
CALL MSG()
END
这是我的问题:
范围
如果我包含 macro.h,则定义宏 MSG()
的位置(全局、本地 SUBROUTINE
等)是:
-
在文件的开头(如上)?
在
PROGRAM display
的开头(没有其他地方)?
在例如开头SUBROUTINE another_message()
(别无他处)?
从测试看来:1. 全局,2. 在PROGRAM
和所有SUBROUTINES
,3. 在那个SUBROUTINE
中。对这些假设的确认和一些理论上的解释为什么会很棒。
上述 (1. - 3.) 中哪些是预处理器的最佳实践包括?
包括警卫
如果我有一个多文件项目并且我在多个 *.F 源文件中包含 header.h,我是否需要提供包含保护?
如果上述问题的答案取决于编译器(因为预处理不是 Fortran 标准),我最感兴趣的是 ifort 的行为。
【问题讨论】:
【参考方案1】:规则与您知道的 C 预处理器相同。 GCC 甚至对 C 和 Fortran 使用相同的 cpp
(对于传统模式下的 Fortran)。因此没有范围,一切都只是一个文本,预处理器不关心程序单元。
因此,1.、2. 和 3. 从定义位置到文件结束或直到 #undef
都是有效的。它们在递归 #include
d 文件中也有效。
如果守卫是指#undef
,那么是的,否则会出现有关重新定义的警告或错误,但前提是您将所有这些文件都包含在一个文件中。如果他们是独立的,那么没有。
关键是将预处理器视为文本替换工具。它对 Fortran一无所知。
最后一点,预处理器是非标准的,但可以广泛使用。
【讨论】:
以上是关于力学 Fortran 预处理器的主要内容,如果未能解决你的问题,请参考以下文章