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
。因此,它类似于我最初建议的字符串化技巧。。。