2016-10-19 1 views
3

Я пишу систему описания макета на основе x-macro для моего проекта. В большинстве случаев макросы расширяются до иерархии классов шаблонов. Тем не менее, я также хочу перечислить все регистры, например:Где мои запятые исчезают в расширении вариационного макроса?

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

enum Regs 
{ 
#include REGDEF 
}; 

Это работает просто отлично. Однако я также указываю регистры псевдонимов, используя переменный макрос. Поскольку не существует тривиальный способ лишить запятые между элементами __VA_ARGS__ (не то, что я не знаю, пожалуйста, поправьте меня, если я ошибаюсь), я пишу:

#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__)) 

Теперь, если я пишу

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

запятые в RINT макро исчезают:

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

Если, в свою очередь, я использую RALIAS_4 макрос непосредственно

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

я получаю то, что я ожидал:

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

Я знаю, что НКУ применяется какой-либо нестандартная запятой вскрышной логики вариативного макроса, но это не должно произойти, когда я явно указать -std = C++ 11. Более того, Кланг дал мне то же самое. Тем не менее я не мог найти ничего, что могло бы объяснить это поведение в стандарте (черновике) или в документации GCC.

Что мне не хватает?

Я пробовал GCC 6.1.1 и Clang 3.8.1 на Arch Linux (x86-64). Оба компилятора были установлены из репозитория.

ответ

2

Это:

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

собирается расширяться в:

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

который является макрос, который принимает 8 аргументов, из которых 4 являются пустыми. Вы не получите аргумент "RSP,", вы получите аргумент RSP, а затем отдельно аргумент "".

Смежные вопросы