Man page - va_end(3)

Packages contains this manual

Available languages:

en fr pl ja ru ro de

Manual

stdarg

НАИМЕНОВАНИЕ
БИБЛИОТЕКА
ОБЗОР
ОПИСАНИЕ
va_start()
va_arg()
va_end()
va_copy()
АТРИБУТЫ
СТАНДАРТЫ
ИСТОРИЯ
CAVEATS
ПРИМЕРЫ
СМОТРИТЕ ТАКЖЕ
ПЕРЕВОД

НАИМЕНОВАНИЕ

stdarg, va_start, va_arg, va_end, va_copy - работа со списком переменного количества аргументов

БИБЛИОТЕКА

Стандартная библиотека языка C ( libc , -lc )

ОБЗОР

#include <stdarg.h>

void va_start(va_list ap , last );
type
va_arg(va_list ap , type );
void va_end(va_list
ap );
void va_copy(va_list
dest , va_list src );

ОПИСАНИЕ

Функцию можно вызвать передав ей произвольное количество аргументов разных типов. Во включаемом файле <stdarg.h> объявляется тип va_list и определяется три макроса для пошагового обхода списка аргументов, чьё количество и типы неизвестны вызываемой функции.

В вызываемой функции требуется объявить объект с типом va_list , который используется макросами va_start (), va_arg () и va_end ().

va_start()

Макрос va_start () инициализирует ap для последующего использования в va_arg ()и va_end (), и должен вызываться первым.

Аргумент last это имя последнего аргумента перед списком с переменным количеством аргументов, то есть это последний аргумент, тип которого известен вызывающей функции.

Так как адрес этого аргумента может быть использован в макросе va_start (), он не должен быть объявлен как регистровая переменная, иметь тип функции или массива.

va_arg()

Макрос va_arg () раскрывается в выражение, которое имеет тип и значение следующего аргумента в вызове. Аргумент ap — это va_list ap , инициализированный va_start (). Каждый вызов va_arg () изменяет ap так, что следующий вызов возвращает следующий аргумент. Аргумент type — это имя типа, указанное так, что тип указателя на объект, который имеет указанный тип, можно получить просто добавив * в type .

Первый вызов макроса va_arg () после va_start () вернёт аргумент после last . Последующие вызовы вернут значения оставшихся аргументов.

Если аргументы закончились, или если type не совместим с типом настоящего следующего аргумента (преобразование происходит согласно преобразованию аргументов по умолчанию), может произойти любая ошибка.

Если ap передан в функцию, которая использует va_arg( ap , type ), то значение ap не определено после возврата из функции.

va_end()

Каждый использование va_start () должно завершаться соответствующим вызовом va_end () в той же функции. После вызова va_end( ap ) значение переменной ap не определено. Возможно несколько проходов по списку, если каждый из них начинать va_start () и заканчивать va_end (). Макрос va_end () может быть и функцией.

va_copy()

Макрос va_copy () копирует (ранее инициализированный) список с переменным количеством аргументов src в dest . Его действие такое же, как если бы va_start () применили к dest с тем же аргументом last , после чего было бы совершено такое же количество вызовов va_arg (), которое имеется в текущем состоянии src .

Очевидной реализацией было бы создать переменную с типом va_list , указывающую на стековый фрейм функции с переменным количеством аргументов. В этом случае (безусловно, наиболее распространенном) кажется, что достаточно присвоения

va_list aq = ap;

К сожалению, есть системы, в которых это массив указателей (длиной 1), и нужно делать

va_list aq;
*aq = *ap;

Наконец, в системах, где аргументы передаются через регистры, в va_start () может потребоваться выделить память, сохранить там аргументы, а также индекс следующего элемента для того, чтобы va_arg () мог обойти список. Также va_end () может освобождать выделенную память. Чтобы всё это учесть в C99 добавлен макрос va_copy (), который позволяет показанное выше назначение заменить на

va_list aq;
va_copy(aq, ap);
...
va_end(aq);

Для каждого вызова va_copy () должен быть соответствующий вызов va_end () в той же функции. В некоторых системах нет va_copy (), а есть __va_copy — имя, которое использовалось в черновике стандарта.

АТРИБУТЫ

Описание терминов данного раздела смотрите в attributes (7).

Image grohtml-626388-1.png

СТАНДАРТЫ

C11, POSIX.1-2008.

ИСТОРИЯ

va_start ()
va_arg
()
va_end
()

C89, POSIX.1-2001.

va_copy ()

C99, POSIX.1-2001.

CAVEATS

В отличие от исторических макросов varargs , макросы stdarg не позволяют программистам создать функцию без постоянных аргументов. Эта проблема создаёт работу, в основном, при преобразовании кода varargs в код stdarg , а также есть сложности с функциями с переменным количеством аргументов, которым нужно передать все их аргументы в функцию в виде аргумента с типом va_list , например vfprintf (3).

ПРИМЕРЫ

Функция foo берёт строку с символами формата и печатает аргумент, связанный с каждым таким символом, на основе его типа.

#include <stdio.h>
#include <stdarg.h>
void
foo(char *fmt, ...) /* '...' is C syntax for a variadic function */
{
va_list ap;
int d;
char c;
char *s;
va_start(ap, fmt);
while (*fmt)
switch (*fmt++) {
case 's': /* string */
s = va_arg(ap, char *);
printf("string %s\n", s);
break;
case 'd': /* int */
d = va_arg(ap, int);
printf("int %d\n", d);
break;
case 'c': /* char */
/* need a cast here since va_arg only
takes fully promoted types */
c = (char) va_arg(ap, int);
printf("char %c\n", c);
break;
}
va_end(ap);
}

СМОТРИТЕ ТАКЖЕ

vprintf (3), vscanf (3), vsyslog (3)

ПЕРЕВОД

Русский перевод этой страницы руководства разработал(и) Alexander Golubev <fatzer2@gmail.com>, Azamat Hackimov <azamat.hackimov@gmail.com>, Hotellook, Nikita <zxcvbnm3230@mail.ru>, Spiros Georgaras <sng@hellug.gr>, Vladislav <ivladislavefimov@gmail.com>, Yuri Kozlov <yuray@komyakino.ru>, Иван Павлов <pavia00@gmail.com> и Kirill Rekhov <krekhov.dev@gmail.com>

Этот перевод является свободной программной документацией; он распространяется на условиях общедоступной лицензии GNU (GNU General Public License - GPL, https://www.gnu.org/licenses/gpl-3.0.html версии 3 или более поздней) в отношении авторского права, но БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ.

Если вы обнаружите какие-либо ошибки в переводе этой страницы руководства, пожалуйста, сообщите об этом разработчику(ам) по его(их) адресу(ам) электронной почты или по адресу списка рассылки русских переводчиков .