我在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)
这应该定义名为GetVersion
和GetkProp
的方法。
现在,这在gcc C ++ 14(实际上是TDM-GCC-64)下发出以下错误:
pasting "(" and "kProp" does not give a valid preprocessing token
如何编写以便在 gcc C ++ 14 和 msvc 2015 下进行编译?
答案 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();
}
您的原始代码似乎与MSVC一起使用的原因是因为MSVC预处理器非常不符合要求 - 它在字符流(错误)上运行,而不是在令牌流(右)上运行。在CLASS_JS_PSG_PROPERTY_EX(##VALUE, VALUE)
中,##
不是您建议的一元运算符 - 它是将(
和VALUE
粘合到单个标记(VALUE
中的二元运算符。这不是一个有效的预处理令牌,因此该程序格式不正确,这就是GCC抱怨的内容。但是MSVC预处理器后来将这个无意义的令牌分解成碎片(符合预处理器的人永远不会这样做)。