Skip site navigation (1)Skip section navigation (2)
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>