Date: Thu, 10 Oct 2002 05:40:30 +1000 (EST) From: Bruce Evans <bde@zeta.org.au> To: Andrew Gallatin <gallatin@cs.duke.edu> Cc: Peter Wemm <peter@wemm.org>, <freebsd-arch@FreeBSD.ORG> Subject: Re: lp64 vs lp32 printf Message-ID: <20021010051056.C6361-100000@gamplex.bde.org> In-Reply-To: <15780.26700.615985.133379@grasshopper.cs.duke.edu>
next in thread | previous in thread | raw e-mail | index | archive | help
On Wed, 9 Oct 2002, Andrew Gallatin wrote:
> Peter Wemm writes:
> > >
> > > Um, using intmax_t to print size_t's would be incorrect, since it is
> > > signed. Using uintmax_t would be bloat. Very few typedefed types
> > > need the full bloat of [u]intmax_t, and size_t is unlikely to become
> > > one of them before casting it to uintmax_t to print it becomes a style
> > > bug in the kernel too (when %z is implemented).
> >
> > Bring it on! The sooner %z gets here the better. The only problem is that
> > gcc has been taught that %z means something different in the kernel. :-(
>
> Where is gcc taught these things? Can we update it?
From c-format.c:
%%%
/* BSD conversion specifiers. */
/* FreeBSD kernel extensions (src/sys/kern/subr_prf.c).
The format %b is supported to decode error registers.
Its usage is: printf("reg=%b\n", regval, "<base><arg>*");
which produces: reg=3<BITTWO,BITONE>
The format %D provides a hexdump given a pointer and separator string:
("%6D", ptr, ":") -> XX:XX:XX:XX:XX:XX
("%*D", len, ptr, " ") -> XX XX XX XX ...
*/
{ "D", 1, STD_EXT, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "cR" },
{ "b", 1, STD_EXT, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "" },
{ "rz", 0, STD_EXT, { T89_I, BADLEN, BADLEN, T89_L, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0 +#", "i" },
{ NULL, 0, 0, NOLENGTHS, NULL, NULL }
%%%
The "z" in "rz" here gives the FreeBSD extension.
There seem to be no conflicts in practice, because %z is a format specifier
(like %z) in the extension, but is (bogusly) a length modifer (like %l)
in C99. Plain %z (which can only be reasonably interpreted as a format
specifier) is implemented by the T89_I entry in the above table. This is
broken, because -fformat-extensions (brokenly) doesn't turn off the things
that are not supported by the kernel printf (e.g., %z as a length modifier),
and gcc interprets %z as a length modifier first. But this is harmless
because plain %z is not used in the kernel. %lz is used and still works
because there is no ambiguity for %z. This is implemented by the T89_L
intry in the above table. Format checking for printing size_t's using
%zu (or %zd) works too, since there is no ambiguity.
Bruce
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-arch" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20021010051056.C6361-100000>
