Re: Strange ipfw change (Sparc bugfix?)

pacman (pacman-kernel@cqc.com)
Wed, 9 Sep 1998 23:54:31 -0500 (EST)


Geert Uytterhoeven writes the following:
>
>On Wed, 9 Sep 1998, Marc Duponcheel wrote:
>>
>> Sorry my ignorance but what does qualifier 'h' (implemented by
>> vsprintf in kernel) actually mean in the printf family?
>> the code goes like this:
>>
>> if (qualifier == 'h') {
>> if (flags & SIGN)
>> num = va_arg(args, short);
>> else
>> num = va_arg(args, unsigned short);
>> }

Attempting to get a short out of va_arg should set off major alarms. It's
impossible to pass a short in a variadic argument list, because the argument
promotion rules will make it into an int. Therefore va_arg(foo, short) is
always incorrect, regardless of context, no matter what foo may be. (The same
is true off va_arg'ing chars and floats. They will become ints and doubles.)
gcc should have a warning about this...

>
>man 3 printf
>
>`h' means the following argument is to be considered a short.
>

Right. It is interpreted as a short, but what is actually passed is an int,
so it must be taken with va_arg(thingy, int) and then cast to short, as seen
in this example taken from glibc, where the presence of the h flag has been
stored in a variable called "is_short", and l is in "is_long":

if (is_long) \
number.word = va_arg (ap, unsigned long int); \
else if (!is_short) \
number.word = va_arg (ap, unsigned int); \
else \
number.word = (unsigned short int) va_arg (ap, unsigned int); \

Notice that the long flag is handled by va_arg'ing a long, but the short flag
is handled by va_arg'ing a short and casting it to long. If printk is going
to support %hd with the same meaning as the normal printf, it should do
something similar.

-- 
Alan Curry

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/faq.html