Подтвердить что ты не робот

Являются ли переменные макросы нестандартными?

Для debugbuild я обычно использую Clang, так как он лучше форматирует предупреждения и ошибки и немного упрощает их отслеживание и исправляет их.

Но недавно после добавления макроса с переменными аргументами, Кланг рассказал мне следующее (из фиктивного проекта):

main.cpp:5:20: warning: named variadic macros are a GNU extension [-Wvariadic-macros]
#define stuff3(args...)  stuff_i(args)

Я знаю, что macroname(args...) компилируется в широком диапазоне компиляторов, включая Visualstudio, Sunstudio и, конечно же, GCC. Но чтобы убедиться, что clang прав, я попробовал еще два способа расширения вариативных аргументов:

Номер 1:

#define stuff1(...)  stuff_i(...)

Номер 2:

#define stuff2(...)  stuff_i(__VA_ARGS__)

На обоих я получаю это сообщение:

main.cpp:3:16: warning: variadic macros were introduced in C99 [-Wvariadic-macros]

... Заставляет меня задаться вопросом, действительно ли макросы Variadic являются частью стандарта С++ (и, конечно, я знаю, что препроцессор интерпретируется независимо)?

4b9b3361

Ответ 1

Цитировать Wikipedia:

Макросы с переменным аргументом были введены в 1999 году в версии стандарта ISO/IEC 9899: 1999 (C99) стандарта языка C, а в 2011 году - в версии ISO/IEC 14882: 2011 (С++ 11) версии языка С++ стандарт.

Итак, он стандартный от C99 и С++ 11, но расширение GNU в С++ 03.

Ответ 2

Начиная с С++ 11, переменные макросы теперь включены в стандартный С++. В разделе 16.3 стандарта С++ 11 указаны переменные макросы, так что они совместимы с переменными макросами из C99 (вторая форма в вопросе).

Ниже приведен пример стандартного определения макрокоманды в С++:

#define foo(x, y, ...)    bar(x, y, __VA_ARGS__)

Ответ 3

В форме вашего примера "Номер 2" они являются стандартными для C99, и, как правило, препроцессор компилятора С++ является одинаковым для компиляции C и С++.

Они также поддерживаются Microsoft VС++, несмотря на его стойкое сопротивление C99. Поэтому между этим и GCC есть несколько причин, чтобы избежать их использования. Даже на большинстве встроенных систем, которые я использую, они поддерживаются.

Избегайте формы "Номер 1", но это твердое значение GCC и, без сомнения, устарело.

Ответ 4

Стандарт говорит в 16.3. Замена макроса:

Идентификатор _ _ VA_ARGS _ _ должен появляться только в списке заметок функционально-подобного макроса, который использует эллипсиса в параметрах.