Spec-Zone.ru › GCC 11

Следующая: Несколько менее строгие правила для экранированных символов новой строки, Предыдущая: Массивы переменной длины, Вверх: Расширения для семейства языков C [Содержание][Индекс]

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-11.4.0/gcc/Variadic-Macros.html

Spec-Zone.ru

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