0

既存の 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
4

1 に答える 1

1

プリプロセッサが再帰を検出するのはなぜですか? [編集] - マクロと識別子に同じ名前を使用しているからでしょうか?

マクロ名と配列名が同じであるため、プリプロセッサは再帰を検出しています。

プリプロセッサが大文字のディレクティブ (#define ではなく #DEFINE) を解釈できないのはなぜですか? - ifort プリプロセッサでこの問題が発生したことがないため、質問しています。

gfortran を使用する場合、C プリプロセッサを使用しています。#DEFINE は、C で認識されるプリプロセッサ ディレクティブではありません。ifort についてはわかりません。私は、マクロの前に !$MS または !$DEC を付ける必要があると思っていました。

ifort で動作するようにプログラムを変更すると、gfortran でも動作します。

于 2013-09-15T08:33:37.930 に答える