Spec-Zone.ru › GCC 6

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

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

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

Spec-Zone.ru

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