Страницы

Поиск по вопросам

среда, 16 января 2019 г.

Раскрытие макросов

Есть маленький вопрос по раскрытиям макросов.
Например, этот код работает:
#define DEF_STRUCT(name, type) struct name {using t = type;}; DEF_STRUCT(hah, int)
И это:
#define DEF_STRUCT(name, type) struct name {using t = type;}; #define BUILD_STRUCT_1(name, type) DEF_STRUCT(name, type) BUILD_STRUCT_1(heh, char)
А вот этот ругается (Требуется спецификатор):
#define DEF_STRUCT(name, type) struct name {using t = type;}; #define BUILD_STRUCT_1(name, type) DEF_STRUCT(name, type) #define BUILD_STRUCT_2(name, type, ...) DEF_STRUCT(name, type) BUILD_STRUCT_1(__VA_ARGS__) BUILD_STRUCT_2(lol, bool, kek, unsigned) // Извини, не хочу работать
Вопрос: как он раскрывается и что следует поменять чтобы заработало как хотелось (Объявление 2-х структур подряд)?


Ответ

Код прекрасно компилируется GCC. В MSVC он не компилируется из-за нестандартного поведения препроцессора. Эту разницу в поведении препроцессора можно проиллюстрировать примером без __VA_ARGS__
#define M2(a, b) #define M1(x) M2(x) /* <- Считается ошибкой в MSVC */ #define A 1, 2 M1(A)
В качестве workaround можно предложить
#define BUILD_STRUCT_2(name, type, name2, ...) \ DEF_STRUCT(name, type) BUILD_STRUCT_1(name2, __VA_ARGS__)
или более общее
#define FIRST(x, ...) x #define TAIL(x, ...) __VA_ARGS__
#define BUILD_STRUCT_2(name, type, ...) \ DEF_STRUCT(name, type) BUILD_STRUCT_1(FIRST(__VA_ARGS__), TAIL(__VA_ARGS__))
Хотя не совсем понятно, зачем здесь ... и __VA_ARGS__ вообще.

Комментариев нет:

Отправить комментарий