Являются ли макросы Variadic нестандартными? - PullRequest
33 голосов
/ 24 января 2011

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

Но недавно после добавления макроса с переменными аргументами,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 частью стандарта C ++ (и, конечно, я знаю, что Препроцессор интерпретируется независимо)?

Ответы [ 4 ]

39 голосов
/ 24 января 2011

Цитата Википедия :

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

Так что это стандарт C99 и C ++ 11 и выше, но расширение GNU в C ++ 03.

28 голосов
/ 08 марта 2012

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

Вот пример стандартного определения вариадического макроса в C ++:

#define foo(x, y, ...)    bar(x, y, __VA_ARGS__)
4 голосов
/ 24 января 2011

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

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

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

0 голосов
/ 06 марта 2012

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

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

...