当前位置: 动力学知识库 > 问答 > 编程问答 >

c++ - Cascaded macros in gcc C++14 vs msvc++ 2015

问题描述:

I have the following code working under 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)

This should define methods named GetVersion and GetkProp.

Now, this gives the following error under gcc C++14 (actually TDM-GCC-64):

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

How should be written in order to compile under gcc C++14 and msvc 2015?

网友答案:

The trick is - if you don't want a name to get expanded as a macro, you must pass it to ## operator right away - but the result of concatenation must be a valid token. Something like this:

#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();
}

Works with gcc and MSVC

The reason your original code appears to work with MSVC is because MSVC preprocessor is famously non-conforming - it operates on a stream of characters (wrong), rather than a stream of tokens (right). In CLASS_JS_PSG_PROPERTY_EX(##VALUE, VALUE), ## is not a unary operator as you suggest - it's a binary operator that glues ( and VALUE into a single token (VALUE. This is not a valid preprocessing token, so the program is ill-formed, which is what GCC complains about. But MSVC preprocessor later breaks this nonsensical token back up into pieces (which a conforming preprocessor would never do).

分享给朋友:
您可能感兴趣的文章:
随机阅读: