Когда вы вызываете одну из функций v*printf
, она использует va_arg
, что означает, что значение ap
является неопределенным при возврате.
Соответствующий бит находится в секции 7.19.6.8 The vfprintf function
в C99,который ссылается на сноску:
As the functions vfprintf, vfscanf, vprintf, vscanf, vsnprintf, vsprintf, and vsscanf invoke the
va_arg macro, the value of
arg after the return is indeterminate.
Это сохранилось до последней версии C1x, которую я имею, так что яподозреваю, что это не изменится быстро.
Нет портативного способа сделать то, что вы пытаетесь, используя функции v*printf
более высокого уровня, хотя вы могли бы прибегнуть к использованию более низкого уровняstuff.
Стандарт очень ясен в том смысле, что вызываемая функция, использующая va_arg
в переменной va_list
, делает ее неопределенной в вызывающей стороне.Начиная с C99 7.15 Variable Arguments <stdarg.h>
:
The object ap may be passed as an argument to another function; if that function invokes the va_arg macro with parameter ap, the value of ap in the calling function is indeterminate and shall be passed to the va_end macro prior to any further reference to ap.
Однако значение ap
при использовании va_arg
в одной функции равно определитель (в противном случае обработка аргументов всей переменной будет нарушена).Таким образом, вы можете написать одну функцию, которая обрабатывает обе строки формата по очереди, с этими функциями более низкого уровня.
При использовании материала более высокого уровня (согласно сноске), вам необходимо va_end/va_start
, чтобы поставитьap
переменная возвращается в определенное состояние, и она, к сожалению, будет сброшена к началу списка параметров.
Я не уверен, насколько упрощением является приведенный вами пример кода, но, если он близок к реальностиВы можете получить тот же результат, просто предварительно скомбинировав две строки формата и используя его для передачи в vprintf
, что-то вроде:
void test(const char* fstra, const char* fstrb, ...) {
char big_honkin_buff[1024]; // Example, don't really do this.
va_list ap;
strcpy (big_honkin_buff, fstra);
strcat (big_honkin_buff, fstrb);
va_start(ap, big_honkin_buff);
vprintf(big_honkin_buff, ap);
va_end(ap);
}