【发布时间】:2016-12-20 13:30:52
【问题描述】:
我正在尝试将源代码中的单词与预处理器宏的扩展连接起来。基本上我在代码中的某处有foo,而#define EXPANSION bar 我想获得foobar。但是,我正在努力寻找一种适用于所有编译器的方法。目前,如果它可以与 gfortran 和 ifort 一起使用,我会很高兴。
根据其documentation,gfortran 预处理器是一个以“传统模式”运行的C 预处理器,它没有## 标记粘贴操作符。但是,使用空的 C 样式 /**/ 注释可以获得相同的效果。 ifort 预处理器的行为似乎更像普通的 C 预处理器,所以普通的标记粘贴在 ifort 中可以解决问题。不幸的是,空的 /**/ 评论在 ifort 中不起作用,因为评论被替换为一个空格。
这是一个小例子:
#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
这对他们俩都有效,但是让预处理器为每个扩展设置条件是相当丑陋的。我宁愿避免这种情况,并且在开始时只使用一次宏魔法。
我在另一个问题上看到this answer,这可能会让我解决这个问题,但我宁愿找到一个不单独调用预处理器的解决方案。
我对 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 在同一行中的扩展。我怀疑这是“传统”C 预处理器的一个特性......
【问题讨论】:
-
我认为答案是定义一个依赖于编译器的
CONCAT函数。这可用于所有扩展。详情见this answer -
感谢您的建议。我已经尝试过这样的事情(请参阅问题的编辑)。不幸的是,无法让它工作......
-
奇怪,
x/**/y产生fooEXPANSION,但 `x/**/ y` 产生foo bar。我建议制定这个问题,以便它吸引 C 预处理器专家并且他们不会跳过它,因为他们会认为它是 Fortran 特定的(事实并非如此)。 -
我想我明白这一点。
CAT的扩展首先发生,产生fooEXPANSION。EXPANSION这个词将不会被进一步扩展,因为它没有被空格分隔。如果您在y之前添加一个额外的空格,则CAT的扩展将产生foo EXPANSION,它将进一步扩展为foo bar。
标签: macros fortran c-preprocessor gfortran intel-fortran