Давайте
class Item{
public:
Item(int id,const char *name,const char *props=NULL);
};
И я хочу написать:
ITEM(1,FIRST);
ITEM(2,SECOND, WithSomeProps);
С макросом
#define ITEM(ID,NAME,...) new Item(ID,NAME, #__VA_ARGS__ )
Тот #__VA_ARGS__
хорошо компилируется на gcc, но выдает ошибку на VStudio. Есть ли надежное и портативное решение?
Я хочу иметь коллекцию ITEM()
в .h файле, который будет включен несколько раз с различными # определениями ITEM
,
GCC и Visual Studio по-разному обрабатывают макросы Variadic, поскольку макросы основаны на препроцессоре компилятора (они раскрываются во время предварительной обработки).
Одно из различий заключается в том, как они обрабатывают пустые переменные макросы.
Один из них позволит пустым __VA_ARGS__
в то время как другой вызовет ошибку компилятора, если __VA_ARGS__
пустой.
На вашем примере первая строка ITEM(1,FIRST)
вызовет ошибку во время компиляции, в то время как работает нормально на другом.
Одним из способов решения этой проблемы является пустой первый аргумент, поэтому ваш конструктор будет выглядеть примерно так:
Item(int id,const char *name,void *allwaysNull, const char *props=NULL);
И тогда у вас есть ваши инициализации макросов, как это
ITEM(1,0,FIRST)
ITEM(2,0,SECOND,WithSomeProps)
Что странно, так это то, что, по моему опыту, именно в GCC возникли проблемы с пустым VA_ARGS
для вариационных макросов …