Вот что было сказано о va_arg
в известной ссылке ниже:
http://www.cplusplus.com/reference/cstdarg/va_arg/
Notice also that va_arg does not determine either whether the retrieved argument is the last argument passed to the function (or even if it is an element past the end of that list). The function should be designed in such a way that the number of parameters can be inferred in some way by the values of either the named parameters or the additional arguments already read.
В дополнение к этому, в так себе книге, из которой я читал о va_arg
, во всех примерах было удостоверено, что один из аргументов fixed
всегда является числом/количеством переменных аргументов, которые мы будем передавать. И это количество используется в цикл, который продвигает va_arg
к следующему элементу, а условие цикла (с использованием счетчика) гарантирует, что он выйдет, когда va_arg
извлечет последний аргумент в списке переменных. Это, кажется, подтверждает приведенный выше абзац с сайта, в котором говорится, что "the function should be designed in such a way........" (above)
.
Таким образом, грубо говоря, va_arg
довольно глупо. Но в следующем примере, взятом с этого веб-сайта для va_end
, внезапно кажется, что va_arg
действует разумно. Когда достигается конец списка переменных аргументов типа char*
, он возвращает указатель NULL. Почему это так? В самом верхнем абзаце, на который я дал ссылку, четко указано
"va_arg does not determine either whether the retrieved argument is the last argument passed to the function (or even if it is an element past the end of that list"
и, кроме того, в следующей программе нет ничего, что гарантирует, что указатель NULL должен быть возвращен, когда конец списка переменных аргументов пересекается. Так почему же va_arg
возвращает указатель NULL здесь, в конце списка?
/* va_end example */
#include <stdio.h> /* puts */
#include <stdarg.h> /* va_list, va_start, va_arg, va_end */
void PrintLines (char* first, ...)
{
char* str;
va_list vl;
str=first;
va_start(vl,first);
do {
puts(str);
str=va_arg(vl,char*);
} while (str!=NULL);
va_end(vl);
}
int main ()
{
PrintLines ("First","Second","Third","Fourth",NULL);
return 0;
}
Вывод
First
Second
Third
Fourth