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

193
28 февраля 2018, 09:26

Есть маленький вопрос по раскрытиям макросов.

Например, этот код работает:

#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-х структур подряд)?

Answer 1

Код прекрасно компилируется 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__ вообще.

READ ALSO
Перенос кода из C++ в C (СИ)

Перенос кода из C++ в C (СИ)

Пытаюсь переписать этот код, написанный на C++ в C (СИ) Код делает следующее: читает str2 если находит * читает str1 от позиции * до ближайшей < потом...

226
Можно ли в Linux делать асинхронные вызовы одного и того-же сокета не защищая его?

Можно ли в Linux делать асинхронные вызовы одного и того-же сокета не защищая его?

Доброго времени сутокПишу клиент-серверное приложение на С++ под Linux

154
Ошибка доступа к памяти в методе класса

Ошибка доступа к памяти в методе класса

Беда следующая: работаю со списком в классе(Использование STL запрещено) худо бедно расписал методыДалее когда описываю экземпляр в main и пытаюсь...

184