我正在尝试将源代码中的单词与预处理器宏的扩展连接起来。基本上,我在代码中有一个
根据其文档,gfortran预处理器是以“传统模式”运行的C预处理器,它没有
以下是一个小例子:
这适用于它们两个,但每次扩展都有预处理器条件相当丑陋。我更愿意避免这种情况,只需要一次在开始时进行一些宏魔法。
foo
,并且使用#define EXPANSION bar
,我想获得foobar
。然而,我很难找到一种适用于所有编译器的方法。暂时来说,如果它能够在gfortran和ifort中运行,我会很高兴。根据其文档,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)
会产生以下输出:
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)
不幸的是,在gfortran中这并不起作用,它会产生fooEXPANSION
。我不完全确定这是如何工作的,但显然CAT
宏的扩展阻止了同一行中EXPANSION
的扩展。我怀疑这是“传统”C预处理器的一个特性...
x/**/y
会产生fooEXPANSION
,但是x/**/ y
会产生foo bar
。我建议将问题表述得更具吸引力,以吸引 C 预处理器专家,让他们不会因为认为这是 Fortran 特定的问题而跳过它(实际上并不是)。 - Vladimir F Героям славаCAT
的扩展首先发生,产生fooEXPANSION
。然后单词EXPANSION
不会进一步扩展,因为它没有被空格分隔开。如果在y
之前加入额外的空格,CAT
的扩展将产生foo EXPANSION
,这将进一步扩展为foo bar
。 - Robert Rüger