Spec-Zone.ru › GCC 15

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

В стандарте 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-15.3.0/gcc/Variadic-Macros.html

Spec-Zone.ru

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