2016-10-19 4 views
3

Ich schreibe ein X-Makro-basierte Register-Datei-Layout-Beschreibungssystem für ein Projekt von mir. Meistens erweitern sich die Makros zu einer Hierarchie von Vorlagenklassen. Ich möchte jedoch auch eine Aufzählung aller Register wie folgt:Wo verschwinden meine Kommas in variadischer Makroexpansion?

#define RINT(num,name,flags,width) name, 
... 

enum Regs 
{ 
#include REGDEF 
}; 

Das funktioniert ganz gut. Ich spezifiziere jedoch auch Aliasing-Register unter Verwendung eines variadischen Makros. Da es keine triviale Weise ist Komma zwischen den Elementen von __VA_ARGS__ abzustreifen (nicht, dass ich von, kenne mich bitte korrigieren, wenn ich falsch liege), schreibe ich:

#define RALIAS_10(r0,r1,r2,r3,r4,r5,r6,r7,r8,r9) r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 
#define RALIAS_9(r0,r1,r2,r3,r4,r5,r6,r7,r8) r0 r1 r2 r3 r4 r5 r6 r7 r8 
... 
#define RALIAS_1(r0) r0 
#define RALIAS_N(d0,d1,d2,d3,d4,d5,d6,d7,d8,d9,aliasn,...) aliasn 
#define RALIAS(...) RALIAS_N(__VA_ARGS__, RALIAS_10(__VA_ARGS__), RALIAS_9(__VA_ARGS__), ..., RALIAS_1(__VA_ARGS__)) 

Nun, wenn ich

RALIAS(RINT(4, RSP, 0, 64), RINT(4, ESP, 0, 32), RINT(4, SP, 0, 16), RINT(4, SPL, 0, 8)) 
schreiben

die Kommas in der RINT Makro verschwinden:

enum Reg 
{ 
... 
RSP ESP SP SPL 
... 
}; 

Wenn wiederum verwende ich das RALIAS_4 Makro

direkt

ich bekommen, was ich erwarten:

enum Reg 
{ 
... 
RSP, ESP, SP, SPL, 
... 
}; 

Ich weiß, dass GCC einige Nicht-Standard-Komma Strippen Logik variadische Makros gilt, aber das sollte nicht passieren, wenn ich ausdrücklich -std = C++ 11 angeben. Außerdem gab mir Clang genau die gleichen Ergebnisse. Ich konnte jedoch nichts finden, was dieses Verhalten im Standard (Entwurf) oder in der GCC-Dokumentation erklären würde.

Was fehlt mir?

Ich versuchte GCC 6.1.1 und Clang 3.8.1 auf Arch Linux (x86-64). Beide Compiler wurden aus dem Repository installiert. Diese

Antwort

2

:

RALIAS(RINT(4, RSP, 0, 64), RINT(4, ESP, 0, 32), RINT(4, SP, 0, 16), RINT(4, SPL, 0, 8)) 

wird sich erweitern in:

RALIAS(RSP,,ESP,,SP,,SPL,) 

, die ein Makro, das 8 Argumente annimmt, davon 4 leer sind. Sie erhalten das Argument "RSP," nicht, Sie erhalten das Argument RSP und dann separat das Argument "".