我正在并行化现有的 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