This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: vfprintf typing problem
On 03/31/2012 10:29 PM, David Miller wrote:
> It's definitely cheaper to do something like:
>
> int overflow = 0;
>
> while (...) {
> ...
> retval *= 10;
> overflow |= ((int) retval < 0);
No, because behavior is undefined after signed overflow,
so a compiler is entitled to optimize the
last line away, so that 'overflow' never becomes nonzero.
GCC actually does that sort of thing sometimes.
Instead, I suggest something like this:
static int
read_int (const UCHAR_T * *pstr)
{
int retval = **pstr - L_('0');
while (ISDIGIT (*++(*pstr)))
if (0 <= retval)
{
if (INT_MAX / 10 < retval)
retval = -1;
else
{
int digit = **pstr - L_('0');
retval *= 10;
if (INT_MAX - digit < retval)
retval = -1;
else
retval += digit;
}
}
return retval;
}
Notice that read_int still parses the entire integer,
even when it overflows; this is simpler to explain and
I expect it may work better with other callers.
Also, please adjust the other seven calls to read_int
(in printf-parsemb.c and in vfprintf.c) to adjust
to read_int's new behavior. This will catch bad formats
with outlandishly large values before '$', which is yet another
bug in this area.