1

我最近正在处理一个 F90 代码项目。我正在使用 gfortran (linux 和 MinGW) 来编译它。loct.F90 文件中有一些有趣的东西。

#  define TYPE real(4)
#  define SUBNAME(x) s ## x
#  include "loct_inc.F90"
#  undef SUBNAME
#  undef TYPE

#  define TYPE real(8)
#  define SUBNAME(x) d ## x
#  include "loct_inc.F90"
#  undef SUBNAME
#  undef TYPE
...

loct_inc.F90 文件如下所示:

subroutine SUBNAME(loct_pointer_copy_1)(o, i)
...
end subroutine SUBNAME(loct_pointer_copy_1)


subroutine SUBNAME(loct_pointer_copy_2)(o, i)
...
end subroutine SUBNAME(loct_pointer_copy_2)


...

我认为在文件 loct.F90 中作者使用了宏集(C/C++ 风格)。每个集合用于定义一种数据类型(例如 real(4)、real(8)、character 等)。loct_inc.F90 文件提供了一组函数,除了变量的类型外,它们是相同的。在我看来,这两个文件作为 c++ 的模板一起工作。

最后应该有一组子程序:

sloct_pointer_copy_1(o, i)
sloct_pointer_copy_2(o, i)
...

dloct_pointer_copy_1(o, i)
dloct_pointer_copy_2(o, i)
...

但是当我尝试编译 loct.F90 (gfortran -c loct.F90) 时,我得到了一些错误。

basic/loct_inc.F90:21.13:包含在 basic/loct.F90:256:

subroutine s ## loct_pointer_copy_1(o, i) 1 错误: (1) 处的 SUBROUTINE 语句中的语法错误

似乎 gfortran 将 SUBNAME(loct_pointer_copy_1)(o, i) 替换为 s ## loct_pointer_copy_1(o, i)。但是根据 c++ 宏,正确的替换应该是 sloct_pointer_copy_1(o, i)。

谁能告诉我为什么会这样?

4

1 回答 1

2

GNU Fortran 在传统模式下使用 GNU C 预处理器,在这种模式下,宏粘贴运算符##不可用。这就是为什么使用 GNU 工具链编译的 Fortran 项目在其他 Makefile 目标中执行显式预处理,例如*.F90,首先将所有项目预处理为然后编译cpp的临时.f90文件。

于 2012-06-03T09:07:07.033 回答