This is the mail archive of the glibc-bugs@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug stdio/18982] New: va_list and vprintf


https://sourceware.org/bugzilla/show_bug.cgi?id=18982

            Bug ID: 18982
           Summary: va_list and vprintf
           Product: glibc
           Version: unspecified
            Status: NEW
          Severity: normal
          Priority: P2
         Component: stdio
          Assignee: unassigned at sourceware dot org
          Reporter: mx2927 at gmail dot com
  Target Milestone: ---

I stumblued in the following problem with va_list and vprintf; consider the
following code sample:

// 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.

Besides the behaviour described in the manual, what I think is particularly
appreciable of the 32bit result is that it fulfils the C standard of arguments
being passed "by value", i.e. the va_list argument to vprintf is passed by
value, thus the original is not modified by vprintf.

Anyway, IMHO, I think that the behaviour should be the same on both
architectures, but even if by design the 32bit result would not be achieved on
64bit, at least the documentation should reflect the actual behaviour.

The problem applies to the family of vprintf functions: vprintf, vfprintf,
vsprintf and vsnprintf.

See also
https://sourceware.org/ml/libc-help/2015-08/msg00038.html
https://sourceware.org/ml/libc-help/2015-09/msg00011.html

-- 
You are receiving this mail because:
You are on the CC list for the bug.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]