Требуется ли для va_copy() va_end()?

#c #c99

#c #c99

Вопрос:

При работе с переменными аргументами требуется только va_start() соответствующий va_end() вызов или va_copy() требуется также сопоставление va_end() , т.е.

 void foo(char *x, ...)
{
  va_list l,c;

  va_start(l,x);
  va_copy(c,l);

  ---
  va_end(c); //is this correct ?
  va_end(l);
}
  

Ответ №1:

Да, каждая копия и оригинал требуют va_end() вызова. Ваш пример верен, порядок ваших va_end() вызовов может быть изменен.

Из ISO / IEC 9899:201x:

7.16.1.3 Макрос va_end

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

В последнем предложении указано, что каждое va_start или va_copy должно сопровождаться va_end возвращением перед возвращением.