Spec-Zone.ru › GCC 4

6.20 Макросы с переменным числом аргументов.

В стандарте ISO C 1999 года макрос может быть объявлен для приема переменного числа аргументов, подобно функции. Синтаксис определения макроса аналогичен синтаксису функции. Вот пример:

#define debug(format, ...) fprintf (stderr, format, __VA_ARGS__)

Здесь ‘...’ — это аргумент переменной длины. При вызове такого макроса он представляет собой ноль или более токенов до закрывающей скобки, завершающей вызов, включая любые запятые. Этот набор токенов заменяет идентификатор __VA_ARGS__ в теле макроса везде, где он встречается. Подробную информацию см. в руководстве CPP.

GCC давно поддерживает макросы с переменным числом аргументов и использует другой синтаксис, который позволяет назначать имя переменным аргументам, как и любому другому аргументу. Вот пример:

#define debug(format, args...) fprintf (stderr, format, args)

Это во всех отношениях эквивалентно приведенному выше примеру ISO C, но, возможно, более удобочитаемо и описательно.

GNU CPP имеет два дополнительных расширения макросов с переменным числом аргументов и позволяет использовать их с любой из вышеприведенных форм определения макроса.

В стандартном C вам не разрешается полностью опустить аргумент переменной длины; но вы можете передать пустой аргумент. Например, этот вызов некорректен в ISO C, потому что после строки нет запятой:

debug ("A message")

GNU CPP позволяет вам полностью опустить аргументы переменной длины таким образом. В приведенных выше примерах компилятор будет жаловаться, хотя при расширении макроса все еще есть дополнительная запятая после строки формата.

Для решения этой проблемы CPP ведет себя особым образом для аргументов переменной длины, используемых с оператором склеивания токенов ‘##’. Если вместо этого вы напишите

#define debug(format, ...) fprintf (stderr, format, ## __VA_ARGS__)

и если аргументы переменной длины опущены или пусты, оператор ‘##’ заставляет препроцессор удалить запятую перед ним. Если вы предоставляете некоторые аргументы переменной длины в своем вызове макроса, GNU CPP не жалуется на операцию склеивания, а вместо этого помещает аргументы переменной длины после запятой. Как и любой другой аргумент склеенного макроса, эти аргументы не подвергаются макроподстановке.

© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-4.9.4/gcc/Variadic-Macros.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API