fpp 宣言子の使用

すべての fpp 宣言子は、行の先頭にシャープ記号 (#) が付きます。最初の "#" の後に、インデント用の余白 (ブランクまたはタブ文字) がくることもあります。

(# 記号から始まる) fpp 宣言子は、ソースコードの任意の場所で (Fortran 継続行の前であっても) 指定できます。ただし、マクロ呼び出し内の fpp 宣言子を、継続記号により複数行に分けることはできません。

fpp 宣言子は、用途ごとに分類することができます。

文字列を代入するための宣言子

fpp には、ユーザーのプログラムで代入を行う宣言子があります。

宣言子

結果

__FILE__

この文字列を入力ファイル名 (文字列) に置換します。

__LINE__

この文字列を入力ファイル中の現在の行番号 (整数定数) に置換します。

__DATE__

この文字列を fpp が入力ファイルを処理した日付 (Mmm dd yyyy 形式の文字列) に置換します。

__TIME__

この文字列を fpp が入力ファイルを処理した時間 (hh:mm:ss 形式の文字列) に置換します。

外部ファイルをインクルードするための宣言子

ファイルのインクルードには、次の 2 つの形式があります。

#include "filename"

#include <filename>

この宣言子は、指定されたファイル内容を、ソースファイルのこの位置に読み取ります。ファイルから読み取られる行は、fpp により、同一ファイルの一部のように処理されます。

<filename> 形式を使用する場合、filename は、標準の "include" ディレクトリー内でのみ検索されます。詳細は、-I オプションと -Y オプションを参照してください。宣言子行の最後にある '"' または ">" の後にトークンを追加することはできません。

ファイルは、次の順に検索されます。

行を制御するための宣言子

この宣言子の形式は次のとおりです。

#line-number "filename"

この宣言子は、Fortran コンパイラーの行制御情報を生成します。line-number は、次の行の号番号を示す整数定数です。"filename" は、行が含まれているファイルの名前です。"filename" が指定されていない場合は、現在のファイル名が使用されます。

fpp 変数とマクロを定義するための宣言子

#define 宣言子は、単純な文字列変数とより複雑なマクロの両方の定義に使用され、次の 2 つの形式があります。

1 つめの形式は、fpp 変数を定義します。

 #define name token-string

この形式では、ソースファイル中の name は、token-string に置換されます。

2 つめの形式は、fpp macro を定義します。

#define name(argument[,argument] ... ) token-string

この形式では、マクロ名 name とそれに続く括弧で囲まれた実引数のカンマ区切りリストは、token-string に置換されます。また、token-string 中の各 argument は、マクロ呼び出しの対応する実引数を表すトークンシーケンスに置換されます。

マクロ呼び出し引数の数が、対応するマクロ定義の引数の数と異なる場合、エラーとなります。例えば、次のマクロ定義について考えてみます。

#define INTSUB(m, n, o) call mysub(m, n, o)

マクロ INTSUB を使用する際には、常に 3 つの引数が必要です。マクロ定義では、マクロ名と開き括弧 "(" の間にスペースを挿入することは禁止されています。これは、マクロ定義が、開き括弧 "(" で始まる token-string を持つ fpp 変数定義として解釈されないようにするためです。

fpp 変数定義またはマクロ定義は、任意の長さにすることが可能で、改行記号によって制限されます。複数行に渡って定義する場合は、行末に "\" を挿入してから次の行に移ります。"\" を挿入せずに改行すると、マクロ定義の終了と見なされます。

例:

#define long_macro_name(x,\
   y) x*y

定義の有効範囲は、#define から現在のファイルの最後までで、その間のすべてのソース行 (および #include ファイルのソース行) が含まれます。ただし、次のものは除きます。

マクロを未定義にするための宣言子

この宣言子の形式は次のとおりです。

#undef name

この宣言子は、(-D オプション、#define 宣言子、またはデフォルトによる) name の定義をすべて削除します。宣言子行の name の後にトークンを追加することはできません。

name が定義されていない場合、#undef 宣言子は効果がありません。

マクロを展開するための宣言子

マクロの展開時に、行のカラム幅が 72 (固定形式) または 132 (自由形式) を超える場合、fpp は適切な Fortran の継続行を挿入します。

固定形式の場合、ラベルフィールドにおけるマクロの展開には制限があります (位置 1-5):

固定形式で fpp -Xw オプションが指定されると、マクロ呼び出しが文の位置で発生し、マクロ名が Fortran のキーワードで始まる場合や Fortran のキーワードと同じ場合、あいまいな状況が発生します。次の例について考えてみます。

#define callp(x)   call f(x)
  call p(0)

この例では、fpp は "call p" をどのように解釈すべきか判断できません。マクロ名と見なされる可能性もあります。現在の実装では、次のことが行われます。

上の例では、マクロが展開され、次の警告が表示されます。

警告: マクロ callp の代入が正しくない可能性があります。

この警告は、固定形式のコードの前処理で、スペースが区切り文字として解釈されない場合にのみ表示されます。

次の場合は、マクロ名がキーワードと同じです。

 #define INT  INTEGER*8
              INTEGER k

INTEGER キーワードは、INT マクロ名よりも先にあります。このようなマクロ定義の前処理では、警告は表示されません。

ソーステキストの条件付き選択を行うための宣言子

ソーステキストの条件付き選択には 3 つの形式があります。

形式 1:

#if condition_1
                 block_1
            #elif condition_2
                 block_2
            #elif ...
            #else
                  block_n
            #endif

形式 2:

          #ifdefname
                 block_1
            #elif condition
                 block_2
            #elif ...
            #else
                 block_n
            #endif

形式 3:

         #ifndef name
                 block_1
            #elif condition
                 block_2
            #elif ...
            #else
                 block_n
            #endif

すべての形式において、elifelse は任意の部分です。各形式で、複数の elif が存在することがあります。

条件式

condition_1condition_2、などは、fpp 定数、マクロ、組み込み関数を含む論理式です。次の演算子を使用することができます。

#ifdef#if defined(name) の省略で、#ifndef#if .not. defined(name) の省略です。

定数式では、これらの演算子、整数定数、名前のみ使用できます。-D オプション、#define 宣言子、またはデフォルトにより宣言されていない名前の値は 0 です。C 演算子の != (等しくない) は、#if 宣言子や #elif 宣言子で使用できますが、! がデフォルトで Fortran のコメント記号と見なされる #define 宣言子では使用できません。

条件付き構造

次の表は、条件付き構造をまとめたものです。

構造

結果

#if condition

condition が .TRUE. の場合のみ、対応する #else#elif、または #endif 宣言子までの行が出力されます。

#ifdef name

#define 宣言子または -D オプションにより name が定義され、介在する #undef 宣言子がない場合のみ、対応する #else, #elif または #endif までの行が出力されます。宣言子行の name の後にトークンを追加することはできません。

#ifndef name

name が定義されていない場合、または #undef 宣言子により定義が削除されている場合のみ、対応する #else, #elif または #endif までの行が出力されます。宣言子行の name の後にトークンを追加することはできません。

#elif condition

次の条件すべてを満たす場合のみ、対応する #else, #elif または #endif までの行が出力されます。

  • 先行する #if 宣言子が .FALSE. の場合、先行する #ifdef 宣言子の name が定義されていない場合、または先行する #ifndef 宣言子の name が定義されている場合。

  • 先行するすべての #elif 宣言子の条件が .FALSE. の場合。

  • 現在の #elif の条件が .TRUE. の場合。

#if 宣言子で許可されている条件がすべて #elif 宣言子でも許可されている場合。#if#ifdef、または #ifndef 宣言子と対応する #else 宣言子または #endif 宣言子の間に #elif がある場合。

#else

次の条件すべてを満たす場合のみ、対応する #endif までの行が出力されます。

  • 先行する #if 宣言子が .FALSE. の場合、先行する #ifdef 宣言子の name が定義されていない場合、または先行する #ifndef 宣言子の name が定義されている場合。

  • 先行するすべての #elif 宣言子の条件が .FALSE. の場合。

#endif

条件付き宣言子 #if#ifdef、または #ifndef によって開始されたセクションを終了します。これらの宣言子には、対応する #endif が必要です。