Есть маленький вопрос по раскрытиям макросов.
Например, этот код работает:
#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__ вообще.
Комментариев нет:
Отправить комментарий