Macros 使用Fortran预处理器连接扩展宏和字

Macros 使用Fortran预处理器连接扩展宏和字,macros,fortran,c-preprocessor,gfortran,intel-fortran,Macros,Fortran,C Preprocessor,Gfortran,Intel Fortran,我试图将源代码中的一个单词与预处理器宏的扩展连接起来。基本上,我在代码中的某个地方有foo,通过#定义扩展栏,我想获得foobar。然而,我正在努力找到一种方法来做到这一点,它适用于所有编译器。目前,如果能与gfortran和ifort合作,我会很高兴 根据its,gfortran预处理器是一个在“传统模式”下运行的C预处理器,它没有##令牌粘贴操作符。但是,使用空的C样式/**/注释也可以获得相同的效果。iPort预处理器的行为似乎更像普通的C预处理器,因此普通的标记粘贴在iPort中起作用。

我试图将源代码中的一个单词与预处理器宏的扩展连接起来。基本上,我在代码中的某个地方有
foo
,通过
#定义扩展栏
,我想获得
foobar
。然而,我正在努力找到一种方法来做到这一点,它适用于所有编译器。目前,如果能与gfortran和ifort合作,我会很高兴

根据its,gfortran预处理器是一个在“传统模式”下运行的C预处理器,它没有
##
令牌粘贴操作符。但是,使用空的C样式
/**/
注释也可以获得相同的效果。iPort预处理器的行为似乎更像普通的C预处理器,因此普通的标记粘贴在iPort中起作用。不幸的是,
/**/
空注释在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
这对它们两个都有效,但是每次扩展都有预处理器的条件是相当丑陋的。我宁愿避免这种情况,在开始时只使用一次宏魔法

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

我对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中不起作用,它在gfortran中生成
fooEXPANSION
。我不完全确定这是如何工作的,但显然,
CAT
宏的扩展阻止了
expansion
在同一行中的扩展。我怀疑这是“传统”C预处理器的一个功能…

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

多亏了一个示例,我找到了一个
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

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

我认为答案是定义一个
CONCAT
函数,该函数取决于编译器。这可以用于所有扩展。有关详细信息,请参阅。有关建议,请参阅。我已经尝试过类似的方法(参见问题的编辑)。不幸的是,它无法工作……奇怪的是,
x/**/y
产生
fooEXPANSION
,但是'x/**/y`产生
foo-bar
。我建议对这个问题进行表述,这样它就能吸引C预处理器专家,他们不会因为认为它是Fortran特有的(事实并非如此)而跳过它。我想我理解这一点。首先进行
CAT
的扩展,生成
fooEXPANSION
。单词
EXPANSION
将不会进一步扩展,因为它没有被空格分隔。如果在
y
之前添加一个额外的空格,则
CAT
的扩展将产生
foo扩展
,该扩展将进一步扩展到
foo bar
。因此,它类似于我最初建议的字符串化技巧。。。