2004 年 2 月 27 日更新


      Sun[tm] Studio 9：Fortran 预处理程序 fpp 自述文件


        目录

        * 简介 <#Intro>
        * 规范 <#Spec>
        * 已知的限制 <#Limitations>

------------------------------------------------------------------------


  简介

Fortran 程序员经常需要维护一种以上的代码版本，或者在各种环境下运行代码。
对于编程人员来说，最容易的解决办法是保留单个源文件，而所有代码变更均相互
穿插在该文件中，这样就可以轻松地提取出任何版本。这样一来，对所有版本均适
用的修改只需进行一次。

源代码预处理程序很早以前就被用于提供这些功能。它们允许用户在源代码中插入
指令语句来影响预处理程序的输出。

通常，这些特殊指令可能作为编译器的注释行出现。一般而言，源代码预处理程序
允许用户定义特殊变量和逻辑构造来有条件地控制文件中哪些源码行将被传送给编
译器，哪些行将被略过。此外，预处理程序的源码行编辑功能允许用户根据所定义
的字符串变量的值来指定如何更改源代码。

在历史上，曾经将标准 C 编译器的源代码预处理程序 cpp 用于向 Fortran 编程
人员提供这些功能。然而，cpp 受到 C 语言语法和源码行格式的紧密束缚，以致
于没有详细审查就不能使用。建议的 Fortran 预处理程序 fpp 将提供 Fortran
特定的源代码功能，C 编程人员曾经期望在 UNIX 环境下实现这些功能。

以下部分将更详细地描述 fpp 的功能。详尽信息参见 fpp(1)
<../man1/fpp.1.html> 手册页。
fpp 的一个实现必须解释和分析 Fortran 源码、评估 Fortran 表达式并生成
Fortran 输出。如果其它工具需要提供一个增强型 Fortran 程序开发环境，这些
功能将是这些工具的构件。

以下部分将更详细地描述 fpp 的功能。详尽信息参见 fpp(1)
<../man1/fpp.1.html> 手册页。

------------------------------------------------------------------------


  详细规范


    fpp 输入源码

fpp 输入源码是散布着预处理程序语句的标准 Fortran 代码。所有预处理程序语
句均以一个特殊字符 # 开头。它只能在一行的第一个字符位置出现。# 后必须紧
跟预处理程序命令的文本。所有预处理程序语句均以一个特殊字符 # 开头。它只
能在一行的第一个字符位置出现。# 后必须紧跟预处理程序命令的文本。

预处理程序指令可能出现在 Fortran 注释内。预处理程序也会修改 Fortran 注释
内的文本。

预处理程序能够对固定和自由格式的源码进行操作。固定格式的源文件以 .F 为扩
展名，而自由格式的源文件以 .F90 为扩展名。请注意，固定格式文件命名约定适
用于 FORTRAN 77 和 Fortran 90。在调用适当的编译器之前，会首先预处理具有
此类扩展名的文件。

如果宏展开或者字符串替换导致一行的列的宽度超过 72 列（固定形式）或者 132
列（自由形式），预处理器将生成适当的续行。


    预处理器变量

预处理程序变量由指令定义并具有一个字符串值。fpp 将在源代码中任何适合替换
的地方用变量的值来替换所出现的变量。变量也会出现在条件指令中，控制传送给
输出的源代码行的选择。

#define name string

将变量“name”的值定义为“string”，“name”标记的每个实例[超出 IMPLICIT 语句
边界，FORMAT 语句和字符串文字中的文本]的结果以“string”照字面意义替换。

注意：如果是 IMPLICIT 语句边界和 FORMAT 语句中的文本，则宏只有在与该范围
内的有效文字相冲突的情况下才不会扩展。

也允许带参数的类“宏”内联替换：
 

#define name (arg1 [,arg2]...) string-with-args-inserted

例子：

#define SOLARIS_2 .TRUE.
#define CONVERT(TO_FARENHEIT) ((TO_FARENHEIT*9)/5)+32

预处理程序变量在从定义点到编译单元结束的整个范围内有效。（即文件的全局范
围）

预处理器变量可以明确的未定义使用

#undef name


    注释

Fortran 预处理器接受包含在 /* 和 */ 之间的 C 风格的注释。


    源代码的条件选择

仿照 cpp 的条件代码结构。

#if condition1
block1
[#elif condition2
block2 ]
...
[#else
blockn ]
#endif

或

#ifdef name
block
#endif
#ifndef name
block
#endif

这些条件是包含预处理程序变量（由 #define 语句指定）的 fpp 表达式。请注
意，条件可在括号内指定。这些 fpp 表达式是 cpp 表达式的超集，它们可以评估
Fortran 逻辑文字。因此，.TRUE. 在 fpp 表达式中是有效的。预处理程序评估这
些条件以获得一个真或者假的结果。这些表达式不能评估浮点值或者包含内函数。

示例：

#define SOLARIS_2 .TRUE.
#if (SOLARIS_2)
CALL solaris_2 (X,Y,Z)
#else
CALL solaris_1 (X,Y,Z)
#endif


    包含文件

有时，在一个文件中收集预处理程序变量是很方便的。可使用下列语句来实现

#include filename

嵌套 #include 是允许的。#include 语句不能出现在续行中（即包含文件中的第
一个语句不能是一个续行）


    预处理器内联函数

defined(name) 提供一个名称的定义状态。根据该名称是否已定义来决定返回的是
TRUE 还是 FALSE。通常用在 #if 语句中：

#if defined(BIG_MODEL)


    命令行选项

fpp 通常从 Fortran 编译器驱动程序中调用。fpp 也可以独立调用。以下是 fpp
接受的一些选项：

-Dname

    定义 name 为 1。这与 fpp 当前正在处理的源文件中出现 #define name1 这
    一行相同。


-Dname=def

    这与 fpp 当前正在处理的源文件中出现 #define name def 这一行相同。


-Idirectory

    “directory”被插入在“include”目录标准列表前面。因此，对于其名称用双引
    号 (") 括起来的 #include 文件，首先在包含 #include 行的文件的目录中
    搜索，然后在以 -I 选项命名的目录中搜索，最后在标准列表内的目录中搜索。


-Uname

    删除“name”的所有初始定义，其中“name”由预处理程序进行预定义。


-Ydirectory

    搜索 #include 文件时使用“directory”来替换目录的标准列表。

------------------------------------------------------------------------

有关使用 fpp 的详细信息，参见 fpp(1) <../man1/fpp.1.html> 手册页。fpp 源
代码可以从 NetLib 下载，网址：http://ww.netlib.org/fortran
<http://www.netlib.org/fortran>

------------------------------------------------------------------------


  已知的限制

    * 第 1-6 列中的宏： 在固定格式文件中（例如，带 .F 扩展名的文件），
      fpp 不扩展第 1 至第 6 列中出现的宏。对于固定格式文件，fpp 遵守
      Fortran 规则，不期望在某一行的前 6 列中或 72 列之后发现语句。唯一
      的解决办法是使用自由格式（.F90 或 .F95 文件）。如果不可能实现这一
      点，则使用 cpp，它将扩展前 6 列中的宏。(4315099)

 

------------------------------------------------------------------------

版权所有 2004 Sun Microsystems, Inc.。 保留所有权利。须按照许可条款进行使用。

