0

我正在并行化现有的 FORTRAN 应用程序。我不想直接更改它的部分代码,所以我使用预处理器指令来实现我的目标。这样我就能够保持代码的可读性,并且不会在已经测试过的部分代码中引发错误。但是,当我尝试使用 GNU C 预处理器预处理我的源代码时,我收到以下错误消息(gcc 版本 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

看来我正在使用带有宏参数的类似函数的宏。

为什么预处理器检测到递归?[编辑] - 也许是因为我对 Makro 和 Identifier 使用了相同的名称?
为什么预处理器不能解释大写指令(#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

为什么预处理器检测到递归?[编辑] - 也许是因为我对 Makro 和 Identifier 使用了相同的名称?

预处理器正在检测递归,因为您的宏名称和数组名称相同。

为什么预处理器不能解释大写指令(#DEFINE 而不是#define)?- 我在问,因为 ifort 预处理器没有这个问题。

使用 gfortran 时,您使用的是 C 预处理器。#DEFINE 不是 C 中公认的预处理器指令。不知道 ifort。我认为在 ifort 中,您必须在宏前面加上 !$MS 或 !$DEC。

您对程序的更改以使其适用于 ifort 也适用于 gfortran。

于 2013-09-15T08:33:37.930 回答