使用 Fortran 预处理器连接展开的宏和单词

Concatenating an expanded macro and a word using the Fortran preprocessor

我正在尝试将源代码中的一个词与预处理器宏的扩展连接起来。基本上我在代码的某处有 foo,并且我想获得 foobar #define EXPANSION bar。但是,我正在努力寻找一种适用于所有编译器的方法来做到这一点。目前,如果它与 gfortran 和 ifort 一起使用,我会很高兴。

根据其documentation,gfortran预处理器是"traditional mode"中的C预处理器运行,它没有##标记粘贴操作符。但是,使用空的 C 风格 /**/ 注释可以获得相同的效果。 ifort 预处理器的行为似乎更像普通的 C 预处理器,因此普通的标记粘贴在 ifort 中起到了作用。不幸的是,空的 /**/ 注释在 ifort 中不起作用,因为注释被单个 space 代替。

这是一个小例子:

#define EXPANSION bar
#define CAT(x,y) PASTE(x,y)
#define PASTE(x,y) x ## y

foo/**/EXPANSION   
CAT(foo,EXPANSION)

gfortran 为其生成:

foobar
foo ## bar

虽然 ifort 给我:

foo bar
foobar

当然,我可以通过检查两个编译器的预定义宏来选择正确的方法:

#ifdef __GFORTRAN__
foo/**/EXPANSION
#else
CAT(foo,EXPANSION)
#endif

这对他们两个都有效,但是让预处理器对每个扩展都有条件是相当丑陋的。我宁愿避免这种情况,一开始只使用一次宏魔法。

我已经看到 另一个问题,这可能会让我解决这个问题,但我宁愿找到一个不单独调用预处理器的解决方案。

我对 C 预处理器不太熟悉。也许有一种简单的方法可以做我想做的事。有什么想法吗?

编辑: 我已经试过这样的东西了:

#define EXPANSION bar
#define CAT(x,y) PASTE(x,y)
#ifdef __GFORTRAN__
#define PASTE(x,y) x/**/y
#else
#define PASTE(x,y) x ## y
#endif

CAT(foo,EXPANSION)

不幸的是,这在生成 fooEXPANSION 的 gfortran 中不起作用。我不完全确定这是如何工作的,但显然 CAT 宏的扩展阻止了 EXPANSION 在同一行中的扩展。我怀疑这是 "traditional" C 预处理器的一个特性 ...

我做了一些研究,似乎基本上大多数 Fortran 编译器(即 Intel 和 PGI)都使用带有标记粘贴运算符的相对普通的 C 预处理器。我们只需要对 gfortran 进行特殊处理,它在传统模式下使用 C 预处理器,没有标记粘贴运算符。

多亏了 entry on c-faq.com,我发现了一个 CAT 宏的定义,它适用于我目前测试过的所有编译器:

#ifdef __GFORTRAN__
#define PASTE(a) a
#define CAT(a,b) PASTE(a)b
#else
#define PASTE(a) a ## b
#define CAT(a,b) PASTE(a,b)
#endif

另一个解决方案(仍然使用 /**/ 技巧)由 Jonathan Leffler in this answer 发布到相关问题。