2016-07-21 4 views
1

Ich habe den folgenden Code unter msvc Arbeits 2015:Kaskadiert Makros in gcc C++ 14 vs 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) 

Dies sollte Methoden GetVersion und GetkProp Namen definieren.

Nun, dies gibt den folgenden Fehler unter gcc C++ 14 (tatsächlich TDM-GCC-64):

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

Wie soll in Reihenfolge geschrieben werden unter gcc zu kompilieren C++ 14 und msvc 2015?

+0

Versuchen Sie 'CLASS_JS_PSG_PROPERTY_EX (VALUE, VALUE)'. – melpomene

+0

In diesem Fall würde es versuchen, Funktionen mit einem Namen als "Get" Version "' oder "Get" kProp "' zu generieren. – mike

+0

Das sollte nur mit '# VALUE' geschehen, nicht mit' VALUE'. – melpomene

Antwort

2

Der Trick ist - wenn Sie nicht möchten, dass ein Name als Makro erweitert wird, müssen Sie es sofort ## Operator weitergeben - aber das Ergebnis der Verkettung muss ein gültiges Token sein. Etwas wie folgt aus:

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

Arbeiten mit gcc und MSVC

Der Grund Ihrer ursprünglichen Code erscheint mit MSVC zu arbeiten, weil MSVC Präprozessor ist bekanntlich nicht-konforme - es auf einem Strom von Zeichen arbeitet (falsch) , anstatt einen Strom von Marken (rechts). In CLASS_JS_PSG_PROPERTY_EX(##VALUE, VALUE), ## ist kein unärer Operator, wie Sie vorschlagen - es ist ein binärer Operator, der ( und VALUE in einem einzigen Token klebt. Dies ist kein gültiges Vorverarbeitungstoken, daher ist das Programm schlecht angelegt, worüber GCC sich beschwert. Aber der MSVC-Präprozessor bricht dieses unsinnige Token später in Stücke (was ein konformer Präprozessor niemals tun würde).