This is the mail archive of the
libc-help@sourceware.org
mailing list for the glibc project.
va_list and vprintf
- From: mx2927 <mx2927 at gmail dot com>
- To: libc-help at sourceware dot org
- Date: Sun, 30 Aug 2015 17:36:40 +0200
- Subject: va_list and vprintf
- Authentication-results: sourceware.org; auth=none
Hi all,
I stumbled in the following problem, which is easily explained by the
following example code:
// begin
#include <stdio.h>
#include <stdarg.h>
void do_print(char* fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vprintf(fmt, ap);
vprintf(fmt, ap);
va_end(ap);
}
int main()
{
do_print("Hello %d, %d, %d\n", 1, 2, 3, 4, 5, 6);
return 0;
}
// end
The libc manual says about vprintf:
"GNU C does not have such restrictions. You can safely continue to fetch
arguments from a va_list pointer after passing it to vprintf, and va_end
is a no-op. (Note, however, that subsequent va_arg calls will fetch the
same arguments which vprintf previously used.)"
The restrictions mentioned are that the va_list pointer becomes invalid
after a call to vprintf:
http://www.gnu.org/software/libc/manual/html_node/Variable-Arguments-Output.html#Variable-Arguments-Output
glibc 2.20 on i686 (Fedora21) output of the above sample is:
Hello 1, 2, 3
Hello 1, 2, 3
Which is as expected according to the description from the manual.
glibc 2.20 on x86_64 (Fedora21) output of the above sample is:
Hello 1, 2, 3
Hello 4, 5, 6
which shows that the va_list pointer is not handled according to the
description from the manual. In fact if the example would provide only 3
variable arguments, the 32bit implementation would keep the va_list
pointer valid, while the 64 bit implementation would make the pointer
invalid.
I know this can be solved using 2 va_list's, or va_copy, but I was
understanding from the manual description that the code above would be
safe. And it should behave coherently on different architectures.
What am I missing here?
(I couldn't test on 2.22, but I saw nothing related in the changelogs)
Thanks in advance,
mmanfred