gcc C ++ 14与msvc ++ 2015中的级联宏

时间:2016-07-21 20:34:41

标签: c++ gcc visual-c++

我在msvc 2015下使用以下代码:

#define CLASS_JS_PSG_PROPERTY_EX(PROPERTY, VALUE) \
static bool Get##PROPERTY(/*irrelevant params here...*/) \
{ \
...
 some particular code
...
    return true; \
}

#define CLASS_JS_PSG_PROPERTY(VALUE) \
CLASS_JS_PSG_PROPERTY_EX(##VALUE, VALUE)

...

#define kProp 1

CLASS_JS_PSG_PROPERTY_EX(Version, kProp)

CLASS_JS_PSG_PROPERTY(kProp)

这应该定义名为GetVersionGetkProp的方法。

现在,这在gcc C ++ 14(实际上是TDM-GCC-64)下发出以下错误:

pasting "(" and "kProp" does not give a valid preprocessing token

如何编写以便在 gcc C ++ 14 msvc 2015 下进行编译?

1 个答案:

答案 0 :(得分:2)

诀窍是 - 如果您不希望将名称扩展为宏,则必须立即将其传递给##运算符 - 但连接的结果必须是有效的标记。像这样:

#include <iostream>

#define CLASS_JS_PSG_PROPERTY_EX_HELPER(GetName) \
static bool GetName() { return true; }


#define CLASS_JS_PSG_PROPERTY_EX(PROPERTY, VALUE) \
CLASS_JS_PSG_PROPERTY_EX_HELPER(Get##PROPERTY)

#define CLASS_JS_PSG_PROPERTY(VALUE) \
CLASS_JS_PSG_PROPERTY_EX_HELPER(Get##VALUE)


#define kProp 1

CLASS_JS_PSG_PROPERTY_EX(Version, kProp)

CLASS_JS_PSG_PROPERTY(kProp)

int main() {
    std::cout << GetVersion() + GetkProp();
}

适用于gccMSVC

您的原始代码似乎与MSVC一起使用的原因是因为MSVC预处理器非常不符合要求 - 它在字符流(错误)上运行,而不是在令牌流(右)上运行。在CLASS_JS_PSG_PROPERTY_EX(##VALUE, VALUE)中,##不是您建议的一元运算符 - 它是将(VALUE粘合到单个标记(VALUE中的二元运算符。这不是一个有效的预处理令牌,因此该程序格式不正确,这就是GCC抱怨的内容。但是MSVC预处理器后来将这个无意义的令牌分解成碎片(符合预处理器的人永远不会这样做)。