2016-07-17 9 views
1

Also das ist mein Code:Warum generiert dieser Makro einen Syntaxfehler?

// Defines a tuple 
#define __WINDOW__RESOLUTION__ 500, 200 

// Seperate the tuple 
#define __WINDOW__X__1(Width, Height) (Width) 
#define __WINDOW__Y__1(Width, Height) (Height) 

// Add another sort of indirection because my tuple is a macro 
#define __WINDOW__X__(Macro) __WINDOW__X__1(Macro) 
#define __WINDOW__Y__(Macro) __WINDOW__Y__1(Macro) 

// These should be the final values 500 and 200 
#define __WINDOW__RESOLUTION__X__ (__WINDOW__X__(__WINDOW__RESOLUTION__)) 
#define __WINDOW__RESOLUTION__Y__ (__WINDOW__Y__(__WINDOW__RESOLUTION__)) 

Als ich das erste Makro verwenden, wo die endgültige Zahl sollte etwas schief zu gehen scheint:

std::cout << __WINDOW__RESOLUTION__X__ << std::endl; // Outputs 200 instead of 500 

über die Linie gibt die Zahl 200, so dass der Y Wert anstelle des X-Wert

std::cout << __WINDOW__RESOLUTION__Y__ << std::endl; // ERR with macro underlined 

diese Linie nicht einmal kompiliert [C2059, Syntaxfehler: ")"]

Vielen Dank für Ihre Hilfe Alex

+3

[Verwenden Sie keine Namen mit zwei führenden Unterstrichen oder ein Unterstrich, gefolgt von einer oberen - Großbuchstaben, die in allen Bereichen reserviert sind] (http://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-ac-identifier). –

+1

Wie für Ihr Problem, sagen Sie Ihrem Compiler, den vorverarbeiteten Code zu generieren und es anzusehen. –

+2

Ich fürchte den Tag Ich werde so etwas in Produktionscode finden ... Sie sind vertraut mit der allgemeinen Richtlinie, dass die Verwendung des Präprozessors so begrenzt wie möglich sein sollte, oder? Warum benutzen Sie nicht einfach 'const int WindowX = 500; const int FensterY = 200; '? –

Antwort

1

Für den Rekord - ich verstehe, dass Ihre Lösung ist "tun Sie das nicht", aber ich wollte immer noch eine Antwort auf die ursprüngliche Frage geben.

In der Tat sehe ich eigentlich nichts falsch mit Ihrem Code. Es funktioniert tatsächlich gut, wenn Sie es mit einem einfachen Test Beispiel wie diese kompilieren:

// Defines a tuple 
#define __WINDOW__RESOLUTION__ 500, 200 

// Seperate the tuple 
#define __WINDOW__X__1(Width, Height) (Width) 
#define __WINDOW__Y__1(Width, Height) (Height) 

// Add another sort of indirection because my tuple is a macro 
#define __WINDOW__X__(Macro) __WINDOW__X__1(Macro) 
#define __WINDOW__Y__(Macro) __WINDOW__Y__1(Macro) 

// These should be the final values 500 and 200 
#define __WINDOW__RESOLUTION__X__ (__WINDOW__X__(__WINDOW__RESOLUTION__)) 
#define __WINDOW__RESOLUTION__Y__ (__WINDOW__Y__(__WINDOW__RESOLUTION__)) 

#include <iostream> 
using namespace std; 

int main() { 
    // your code goes here 
    std::cout << __WINDOW__RESOLUTION__X__ << std::endl; 
    std::cout << __WINDOW__RESOLUTION__Y__ << std::endl; 
    return 0; 
} 

Es sieht aus wie Ihre Fehler an den Klammern in Beziehung gesetzt werden kann in Ihrem letzten macro, obwohl, so entfernen sie nur möglicherweise lösen könnte, dass , aber auch hier - das ist nicht für mich erforderlich war (mit gcc 5.4 unter ubuntu):

// These should be the final values 500 and 200 
#define __WINDOW__RESOLUTION__X__ __WINDOW__X__(__WINDOW__RESOLUTION__) 
#define __WINDOW__RESOLUTION__Y__ __WINDOW__Y__(__WINDOW__RESOLUTION__) 

es wurde bereits darauf hingewiesen, dass auch Doppelstrich __ von einem Großbuchstaben gefolgt ist reserviert, aber es ist sicherlich didn‘ t stop gcc von der Erstellung dieser - vielleicht würde es aber einen Fehler mit strengeren Kompilierflags erzeugen!

+0

Danke, dass du mir geholfen hast Chris, ich weiß es wirklich zu schätzen, dass du mir hilfst, weil es ein Do-not-Do ist. Ich weiß es nicht, aber bevor ich mich konzentrieren kann, muss ich die Sprache lernen und du hast mir dabei geholfen, einen Schritt näher zu kommen, also vielen Dank!^_^ – Brogramer

+0

Nun, weißt du, Leute haben ihre Vorliebe, was sollte/sollte nicht getan werden, aber es ist nicht immer an dir (allein), wie der Code aussieht, mit dem du arbeitest, oder? Es wäre gut zu wissen, welchen Compiler Sie auf welcher Plattform verwenden, obwohl – Chris

+0

Auch sollten Sie erwähnen 'using namespace std;' ist eine b ad Idee –

2

Es scheint gut zu funktionieren, wenn mit gcc4.9 kompiliert, aber das Problem könnte darin liegen, dass der Compiler __WINDOW__RESOLUTION__ als ein einziger Parameter threads. Ersetzen Sie beispielsweise, wenn Sie

#define __WINDOW__RESOLUTION__X__ (__WINDOW__X__(__WINDOW__RESOLUTION__)) 

mit

#define __WINDOW__RESOLUTION__X__ (__WINDOW__X__(500, 200)) 

Es wird einen Fehler werfen, weil __WINDOW__X__ nur 1 Parameter erwartet.

Sie können dieses Problem lösen, indem ... und __VA_ARGS__ in Ihrem Makro verwenden, der beliebigen Parameter weiterleiten, die sie empfängt:

#define __WINDOW__X__(...) __WINDOW__X__1(__VA_ARGS__) 
#define __WINDOW__Y__(...) __WINDOW__Y__1(__VA_ARGS__) 
Verwandte Themen