Правило строго из C11 7.16p3 :
Объект ap
[типа va_list
] может быть передан в качестве аргумента другой функции; если эта функция вызывает макрос va_arg с параметром ap, значение ap в вызывающей функции не определено и должно быть передано в макрос va_end
до любой дальнейшей ссылки на ap .
Код:
display(num,ap);
va_arg(ap, ...);
недействителен - как только вы передадите va_list
другой функции, вы сможете только вызвать va_end
. Вы можете взять указатель на va_list
.
{
...
display(num, &ap);
va_arg(ap, int); // ok
va_end(ap);
}
void display(int num, va_list *ap) {
va_arg(*ap, int); // ok
}
Но вы повторяете va_list
дважды - один раз на дисплее и один раз в sum
. va_list
запоминает свою позицию, поэтому для повторения списка дважды вам нужно иметь два va_list
, инициализированных с самого начала. Самый простой в вашем случае - дважды инициализировать va_list
. Итак, вы можете сделать:
int sum(int num, ...) {
va_list ap;
va_start(ap, num);
display(num, ap);
va_end(ap);
int total = 0;
va_start(ap, num);
for (int i = 0; i < num; i++) {
int arg = va_arg(ap, int);
total += arg;
}
va_end(ap);
return total;
}
void display(int num, va_list ap)
{
for(int i = 0; i < num; i++)
{
int argument = va_arg(ap,int);
printf("%d + ",argument);
}
}