Почему va_arg возвращает NULL в конце списка переменных аргументов типа char*?

Вот что было сказано о 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

Ссылка на исходный код программы


person Rüppell's Vulture    schedule 07.05.2013    source источник
comment
Я надеялся, что это не серьезный вопрос, но, видимо, так оно и было.   -  person    schedule 07.05.2013
comment
Может ли кто-нибудь удалить его, пожалуйста? Я никогда не замечал последнюю часть примера. Боже!! Это неловко.   -  person Rüppell's Vulture    schedule 07.05.2013


Ответы (1)


Когда достигается конец списка переменных аргументов типа char *, он возвращает указатель NULL. Как это так?

Поскольку последним переданным в функцию аргументом действительно является NULL:

PrintLines("First", "Second", "Third", "Fourth", NULL);
person Community    schedule 07.05.2013
comment
Хотел удалить перед первым ответом. Но и то нужно голосование. Отлично, теперь все будут смеяться над моим вопросом. - person Rüppell's Vulture; 07.05.2013
comment
@Rüppell'sVulture Мы можем сделать друг друга сторонний фейспалм ;-) - person ; 07.05.2013
comment
Ага, давай, поквитайся со мной за то, что я тебе в тот день сказал, что тайваньцы догоняют венгров :-( - person Rüppell's Vulture; 07.05.2013