【问题标题】:Mechanics Fortran Preprocessor力学 Fortran 预处理器
【发布时间】: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 等)是:

  1. 在文件的开头(如上)?
  2. 在PROGRAM display 的开头(没有其他地方)?
  3. 在例如开头SUBROUTINE another_message()(别无他处)?

从测试看来:1. 全局,2. 在PROGRAM 和所有SUBROUTINES,3. 在那个SUBROUTINE 中。对这些假设的确认和一些理论上的解释为什么会很棒。

上述 (1. - 3.) 中哪些是预处理器的最佳实践包括?

包括警卫

如果我有一个多文件项目并且我在多个 *.F 源文件中包含 header.h,我是否需要提供包含保护?

如果上述问题的答案取决于编译器(因为预处理不是 Fortran 标准),我最感兴趣的是 ifort 的行为。

【问题讨论】:

    标签: scope fortran preprocessor include-guards


    【解决方案1】:

    规则与您知道的 C 预处理器相同。 GCC 甚至对 C 和 Fortran 使用相同的 cpp(对于传统模式下的 Fortran)。因此没有范围,一切都只是一个文本,预处理器不关心程序单元。

    因此,1.、2. 和 3. 从定义位置到文件结束或直到 #undef 都是有效的。它们在递归 #included 文件中也有效。

    如果守卫是指#undef,那么是的,否则会出现有关重新定义的警告或错误,但前提是您将所有这些文件都包含在一个文件中。如果他们是独立的,那么没有。

    关键是将预处理器视为文本替换工具。它对 Fortran一无所知。

    最后一点,预处理器是非标准的,但可以广泛使用。

    【讨论】:

      猜你喜欢
      • 2015-09-29
      • 2021-07-09
      • 2020-04-06
      • 1970-01-01
      • 2018-08-18
      • 1970-01-01
      • 2011-08-29
      • 1970-01-01
      相关资源
      最近更新 更多