Spec-Zone.ru › GCC 12

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

В стандарте 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 не будет жаловаться на операцию склейки, а вместо этого поместит переменные аргументы после запятой. Как и любой другой склеенный аргумент макроса, эти аргументы не подвергаются макрорасширению.

Далее: Экранированные символы новой строки, Предыдущий: Переменная длина, Вверх: Расширения C [Оглавление][Индекс]

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

Spec-Zone.ru

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