cvs commit: src/lib/libc/stdlib getenv.c
brde at optusnet.com.au
Sat Sep 22 04:21:02 PDT 2007
On Sat, 22 Sep 2007, [utf-8] Dag-Erling SmÃ¸rgrav wrote:
> Sean Farley <scf at FreeBSD.org> writes:
>> The precision for a string argument in a call to warnx() needs to be cast
>> to an int to remove the warning from using a size_t variable on 64-bit
> s/to remove the warning/to actually work/
Please be precise :-).
s/to remove the warning ... on 64-bit platforms/to avoid undefined behaviour
on platforms where size_t is not u_int, and to avoid having to make a
delicate analysis to show that the behaviour is defined and correct on
all other platforms/.
- size_t is always an unsigned type, but the required type is int, so
size_t is never compatible with the required type.
- on platforms where size_t is smaller than int, the arg type is
nevertheless compatible with int, since warnx() is variadic and the
arg is one of the variadic args; the default promotions thus apply
and the arg is passed as an int whether or not you cast it explicitly
to int (but casting it to a type larger than int would break it).
FreeBSD doesn't support any platforms in this class.
- on platforms where size_t is u_int, the arg is passed as a u_int.
The analysis for this case is too delicate to give in full here.
- the size_t variable must have a small value that is representable
as an int (else casting it to int would be a bug and/or printing
a line of that length would be a style bug).
- the behaviour seems to have been undefined in C90, since va_arg()
requires strict type compatibility in C90 and warnx() is implemented
using va_arg(ap, int) which gave UB on u_int's. Similarly for
function calls, except the wording is less clear/strict.
- UB in C90 was a bug in C90. This is fixed in C99. Now both va_arg()
and function call args are specifically required to work if one type
is a signed integer type, the [promotion of the] other type is the
corresponding unsigned integer type, and the value is representable
in both types. Compatibility of the representation of integers and
unsigned integers probably also requires this, but the specification
of this in C90 is probably to fuzzy to override the parts that
specify UB. Everyone just knows that this case has to work.
More information about the cvs-src