This blog post утверждает, что прохождение va_list
другой функции, как в следующем коде небезопасно, и что va_list
должны сначала быть скопированы с помощью va_copy
:Можно ли передать va_list другой функции без использования va_copy?
void
foo_ap(const char *fmt, va_list ap)
{
char buf[128];
vsnprintf(buf, sizeof(buf), fmt, ap);
// now, do something with buf ...
}
Как один из комментариев к сообщению в блоге упоминает, я могу Посмотрите, как это будет небезопасно, так как состояние спецификации C99 (7.15):
Объект
ap
может быть передан в качестве аргумента другой функции; если эта функция вызывает макросva_arg
с параметромap
, значениеap
в вызывающей функции является неопределенным и должно быть передано в макросva_end
до любой дополнительной ссылки наap
.
(Пока foo_ap
не ссылается ap
после прохождения его, то вторая часть предложения, кажется, не применяются в любом случае.) Автор блога говорит в другом комментарии, что он может быть неправильно, но, возможно, кто-то может добавить некоторые разъяснения. Должен ли я действительно использовать va_copy
, чтобы быть в безопасности? Или существуют какие-либо платформы, которые не соответствуют спецификации и требуют использования va_copy
?
Сообщение в блоге, кажется, прямо противоречит предложению, указанному в стандарте C99. Автор блога говорит «Давным-давно» в начале этого, поэтому я предполагаю, что он имел дело с какой-то старой, не соответствующей стандартам системой. –
Вам нужно только 'va_copy', если вы все еще планируете использовать' ap' после 'vsnprintf'. Например, вы можете дважды называть 'vsnprintf' - один раз, чтобы определить необходимый размер буфера, и снова форматировать для реального. Если вам не нужно использовать 'ap' снова, за исключением передачи его в' va_end', вам не нужно 'va_copy' его. –
@IgorTandetnik Если вы ответите на свой вопрос, я приму его. – nwellnhof