既存の FORTRAN アプリケーションを並列化しています。コードの一部を直接変更したくないので、プリプロセッサ ディレクティブを使用して目標を達成しています。このようにして、コードの可読性を維持することができ、既にテストされたコードの部分でエラーを引き起こすことはありません。ただし、GNU C プリプロセッサでソースを前処理しようとすると、次のエラー メッセージが表示されます ( gcc version 4.7.2 (Debian 4.7.2-5) )。
test.f:9:0: error: detected recursion whilst expanding macro "ARR""
この簡単なテスト プログラムは、私の問題を示しています。
PROGRAM TEST
IMPLICIT NONE
INTEGER I,OFFSET,ARR(10)
#define ARR(I) ARR(OFFSET+I)
DO I=1,10
ARR(I)=I
END DO
#undef ARR(I)
END PROGRAM TEST
これはコマンドライン出力です:
testing$ gfortran -cpp -E test.f
# 1 "test.f"
# 1 "<command-line>"
# 1 "test.f"
PROGRAM TEST
[...]
test.f:9:0: error: detected recursion whilst expanding macro "ARR"
DO I=1,10
ARR(OFFSET+OFFSET+OFFSET+OFFSET+OFFSET+OFFSET+OFFSET+OFFSET+OFFSET+OFFSET+OFFSET+OFFSET+OFFSET+OFFSET+OFFSET+OFFSET+OFFSET+OFFSET+OFFSET+OFFSET+OFFSET+I)=I
END DO
[...]
END PROGRAM TEST
このサイトでは、私が使用しているプリプロセッサに関する情報を提供しています。
http://tigcc.ticalc.org/doc/cpp.html#SEC10
マクロ引数を持つ関数のようなマクロを使用しているようです。
プリプロセッサが再帰を検出するのはなぜですか? [編集] - マクロと識別子に同じ名前を使用しているからでしょうか?
プリプロセッサが大文字のディレクティブ (#define ではなく #DEFINE) を解釈できないのはなぜですか? - ifort プリプロセッサでこの問題が発生したことがないため、質問しています。
ところで: ifort プリプロセッサ -fpp を使用するか、次の方法でソースを変更することにより、元のコードを前処理することができます。
PROGRAM TEST
IMPLICIT NONE
INTEGER I,OFFSET,ARR(10)
#define ARR_T(I) ARR(OFFSET+I)
DO I=1,10
ARR_T(I)=I
END DO
#undef ARR_T(I)
END PROGRAM TEST