[Top][All Lists]
[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.