bug-glibc
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: BUG: printf formatting libc.so.6


From: bkorb
Subject: Re: BUG: printf formatting libc.so.6
Date: Thu, 29 May 2003 07:40:48 -0700 (PDT)

Segher Boessenkool wrote:
> 
> >>void main(void) { printf("%1$d %1$c %2$d %2$c\n", 32, 49); }
> 
> This fails on ancient glibc's, with ancient gcc's, too.

glibc's %n$ formatting was hopeless.  Forget it.

> The failure mode is more apparent on big-endian systems.

but a problem on all endian machines.

> See  union printf_arg  and how it's used in vfprintf.c .
> 
> The fix is probably to document not to use a positional
> parameter more than once.

Exactly the implementation problem.  There is no such constraint.
The contrary is required, in fact.

Some are trying to claim the existence of weasel words that allow
implementers to trash values if a particular conversion character
uses fewer bits than are contained in an "int".  Such an interp-
retation is:

a)  non-obvious
b)  not helpful.  Libraries are supposed to be as helpful as
    possible, removing as many obstacles as possible.
c)  not correct, but that is a guess.  All I have at hand are
    man pages that say nothing special about %c having side
    effects and Solaris, AIX, HP/UX and SVr5 examples that all
    work just fine.  Only glibc fails.

NAME printf, fprintf, sprintf, snprintf - print formatted output

SYNOPSIS
     .....
DESCRIPTION
     The printf() function places output on the  standard  output
     stream stdout.

     [[...]]

     Conversions can be applied to the  nth  argument  after  the
     format  in the argument list, rather than to the next unused
     argument. In this case,  the  conversion  character  %  (see
     below) is replaced by the sequence %n$, where n is a decimal
     integer in the range [1, NL_ARGMAX], giving the position  of
     the argument in the argument list. This feature provides for
     the definition of format strings that select arguments in an
     order  appropriate  to  specific languages (see the EXAMPLES
     section).

     In format strings containing  the  %n$  form  of  conversion
     specifications,  numbered arguments in the argument list can
     be referenced from  the  format  string  as  many  times  as
     required.

     In format  strings  containing  the  %  form  of  conversion
     specifications,  each  argument in the argument list is used
     exactly once.

The above wording places no constraints on the types of conversions
affecting the "as many times as required" clause.  The description
of the ``c'' conversion character specifies "converting" the arg-
ument to a character and then printing it, but elsewhere the 
conversion is described as a cast, not a trashing of the high order
bits.  I'll guess again here and guess that %c triggers the glibc
printf code to do a byte sized register load and then reuse the
register without reloading to handle the %d element.  If that is
an attempt to save time, it is likely a mistake.  It will often
take more time to load a byte than a word, but not always.  Certainly,
it won't be faster.  If the actual memory used to pass the value
is getting trashed by the code handling the %c, then there are other
problems.  Basically, I see absolutely no compelling need to trash
the argument.  It's a bug.





reply via email to

[Prev in Thread] Current Thread [Next in Thread]