Spec-Zone.ru › GCC 10

Следующая: Несколько более свободные правила для экранированных символов новой строки, Предыдущая: Массивы переменной длины, Вверх: Расширения семейства языков 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-10.5.0/gcc/Variadic-Macros.html

Spec-Zone.ru

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