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
direktich 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