Вопрос

Для Debugbuilds я обычно использую 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. Но просто чтобы убедиться, что Кланг прав, я попробовал два других способа расширения вариационных аргументов:

Номер 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]

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

Это было полезно?

Решение

Цитировать Википедия:

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

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

Другие советы

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

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

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

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

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

Однако избегайте формы «номер 1», которая твердо специфична для GCC и, без сомнения, устарела.

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top