Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
| Newsgroups | comp.std.c |
|---|---|
| Subject | PRI* considered harmful |
| From | "Greg A. Woods" <woods@robohack.org> |
| Message-ID | <87mxgqhk3x.fsf@once.weird.com> (permalink) |
| Date | 2011-07-06 19:58 -0700 |
I've been scratching my head over this ever since I first tried to
actually use the PRI* macros in real-world code, and a recent discussion
about what to do w.r.t. some systems are increasing time_t to be 64 bits
caused me to go searching the Internets further, but to no avail.
Everyone is inventing their own hokey incompatible schemes and nobody is
really benefiting from any improvement in the standard.
PRI* Considered Harmful:
In order to avoid warnings from some versions of GCC (and perhaps other
compilers as well -- I haven't had the recent pleasure) on some types of
systems you will still have to cast some variables declared using
standard typedef names, such as time_t, to the appropriate int*_t type,
even when using an appropriate sized PRI* macro with printf(), eg.g. as
in:
typedef time_t long;
time_t t = 0;
printf("%" PRId32 "\n", (int32_t) t);
That's because often PRId32 is "d", but on the same systems time_t is
known deep down as a "long", not an "int", and GCC doesn't like the use
of a "long" with "%d" (nor should it).
On other systems PRId32 will be "ld" (sadly even on some 32-bit systems
with 32-bit int and long!), and if "int32_t" isn't also known as "long"
down under then you're still screwed.
So, this suggested work-around of casting with the matching-sized int*_t
will only work if the underlying definitions of int*_t match the way
PRId* are defined, and I'm not convinced this is true on all systems
today.
Obviously this suggestion is only half-baked since the whole idea of
typedefs such as time_t is to allow their underlying definition to
change without having to change code everywhere their offspring are
used. Clearly with the above use of every related use of PRId32 and
int32_t would have to change when time_t becomes int64_t.
The next suggestion is inevitably to define a pair of macros:
#if (!defined(HAVE_INTTYPES_H) && \
(defined(__STDC_VERSION__) && \
((__STDC_VERSION__ - 0) >= 199901L) || \
defined(_ISOC99_SOURCE) || \
(defined(__NetBSD_Prereq__) && __NetBSD_Prereq__(1,6,0)) ||\
(defined(__NetBSD_Version__) && (__NetBSD_Version__ >= 106000000)))) /* etc. */
# define HAVE_INTTYPES_H 1
#endif
#ifdef HAVE_INTTYPES_H
# include <inttypes.h>
#endif
#include <time.h>
/* assume time_t is always signed */
#ifndef PRIdTIME
# if SIZEOF_TIME_T == SIZEOF_INT32_T
# define INT_TIME_T int32_t
# define PRIdTIME PRId32
# elif SIZEOF_TIME_T == SIZEOF_INT64_T
# define INT_TIME_T int64_t
# define PRIdTIME PRId64
# endif
#endif
And of course have some configure script that's run before the build
or other template files supply the definitions for the SIZEOF_* macros.
Now we can do:
printf("%" PRIdTIME_T "\n", (INT_TIME_T) t);
Unfortunately this leaves approximately everyone re-inventing this wheel
every time, even for the standard typedef names!
A Teeny Improvement:
I've also seen it suggested that _every_ non-base-integer type _always_
be cast to [u]intmax_t and printed using PRI[ud]MAX:
printf("%" PRIuMAX, (uintmax_t) uival);
printf("%" PRIdMAX, (intmax_t) t); /* for signed values */
Now we're safe for every possible underlying type of any typedef name,
home baked, or standardised.
However if you're always going to do that, then it's far simpler to
avoid the possibly confusing and unnecessarily verbose (and potentially
incorrectly defined) use of PRI*MAX and just use "%jd" or "%ju" as
necessary. The only advantage of PRI*MAX is that it'll make your code
more easily ported to non-conforming environments (i.e. those without
"%jd" et al, and even if PRI*MAX are defined wrong you can still fix it
with #undef).
FYI: The theory here is that the potentially additional heavy lifting
by printf() is trivial compared to the programmer overhead of trying to
find and/or define, and/or use, the right PRI* macros.
A Better Improvement(?):
Too bad printf(3) et al don't have format flag akin to '*' which allows
you to pass the sizeof() and the signedness of an integer type to it so
that you don't have to hard-code the integer size in the format
string....
int128_t foo = -1;
uint64_t ubar = 1;
#define issigned(v) (((typeof(v)) -1 < 0) ? true : false)
#define INTPARAM(v) (int) issigned(v), (int) sizeof(v), v
printf("%Si %Si\n", INTPARAM(foo), INTPARAM(ubar));
(I chose "%i" to suggest somewhat that it's different from "%d" or "%u",
i.e. in that it takes the signedness from the 'S' flag (since I don't
see %i used very often in the code I read -- it's definitely the new kid
on the block, and perhaps it can grow up more with a new meaning), but
of course it need not be -- "%d" and "%u" can also take the sign flag
using the 'S' flag, but that may confuse the novices more often than not.)
(also, issigned should become a new keyword, as should typeof from GCC,
though with the former, the latter isn't needed here :-))
Does anyone else think this would be worthwhile? Better ideas anyone?
--
Greg A. Woods
RoboHack
<woods@robohack.ca> living on the edge http://www.robohack.ca/
Back to comp.std.c | Previous | Next — Next in thread | Find similar | Unroll thread
PRI* considered harmful "Greg A. Woods" <woods@robohack.org> - 2011-07-06 19:58 -0700
Re: PRI* considered harmful William Ahern <william@wilbur.25thandClement.com> - 2011-07-06 20:38 -0700
Re: PRI* considered harmful "Greg A. Woods" <woods@robohack.org> - 2011-07-06 22:26 -0700
Re: PRI* considered harmful Jens Gustedt <Jens.Gustedt@loria.fr> - 2011-07-07 08:52 +0200
Re: PRI* considered harmful "Greg A. Woods" <woods@robohack.org> - 2011-07-07 14:11 -0700
Re: PRI* considered harmful Jens Gustedt <Jens.Gustedt@loria.fr> - 2011-07-08 11:58 +0200
Re: PRI* considered harmful lawrence.jones@siemens.com - 2011-07-07 17:58 -0400
Re: PRI* considered harmful Jens Gustedt <Jens.Gustedt@loria.fr> - 2011-07-08 12:02 +0200
Re: PRI* considered harmful lawrence.jones@siemens.com - 2011-07-07 17:57 -0400
Re: PRI* considered harmful Keith Thompson <kst-u@mib.org> - 2011-07-07 15:42 -0700
Re: PRI* considered harmful lawrence.jones@siemens.com - 2011-07-08 08:56 -0400
Re: PRI* considered harmful James Kuyper <jameskuyper@verizon.net> - 2011-07-07 06:36 -0400
Re: PRI* considered harmful "Greg A. Woods" <woods@robohack.org> - 2011-07-07 12:59 -0700
Re: PRI* considered harmful Keith Thompson <kst-u@mib.org> - 2011-07-07 14:12 -0700
Re: PRI* considered harmful "Greg A. Woods" <woods@robohack.org> - 2011-07-07 15:49 -0700
Re: PRI* considered harmful Keith Thompson <kst-u@mib.org> - 2011-07-07 16:46 -0700
Re: PRI* considered harmful "Greg A. Woods" <woods@robohack.org> - 2011-07-07 18:26 -0700
Re: PRI* considered harmful James Kuyper <jameskuyper@verizon.net> - 2011-07-07 22:35 -0400
Re: PRI* considered harmful "Greg A. Woods" <woods@robohack.org> - 2011-07-07 20:58 -0700
Re: PRI* considered harmful Wojtek Lerch <wojtek_l@yahoo.ca> - 2011-07-08 00:28 -0400
Re: PRI* considered harmful James Kuyper <jameskuyper@verizon.net> - 2011-07-08 07:41 -0400
Re: PRI* considered harmful "Greg A. Woods" <woods@robohack.org> - 2011-07-08 23:05 -0700
Re: PRI* considered harmful Keith Thompson <kst-u@mib.org> - 2011-07-09 00:50 -0700
Re: [incorrectly implementd] PRI* considered harmful James Kuyper <jameskuyper@verizon.net> - 2011-07-09 06:38 -0400
Re: PRI* considered harmful Hans-Bernhard Bröker <HBBroeker@t-online.de> - 2011-07-09 21:07 +0200
Re: PRI* considered harmful Keith Thompson <kst-u@mib.org> - 2011-07-08 09:52 -0700
Re: PRI* considered harmful Richard Kettlewell <rjk@greenend.org.uk> - 2011-07-08 11:45 +0100
Re: PRI* considered harmful "Greg A. Woods" <woods@robohack.org> - 2011-07-08 23:14 -0700
Re: PRI* considered harmful Keith Thompson <kst-u@mib.org> - 2011-07-09 00:47 -0700
Re: PRI* considered harmful Richard Kettlewell <rjk@greenend.org.uk> - 2011-07-09 10:51 +0100
Re: PRI* considered harmful James Kuyper <jameskuyper@verizon.net> - 2011-07-09 06:43 -0400
Re: PRI* considered harmful Keith Thompson <kst-u@mib.org> - 2011-07-08 09:49 -0700
Re: PRI* considered harmful "Greg A. Woods" <woods@robohack.org> - 2011-07-08 23:24 -0700
Re: PRI* considered harmful Keith Thompson <kst-u@mib.org> - 2011-07-09 00:45 -0700
Re: PRI* considered harmful "Greg A. Woods" <woods@robohack.org> - 2011-07-09 16:18 -0700
Re: PRI* considered harmful Keith Thompson <kst-u@mib.org> - 2011-07-09 18:57 -0700
Re: PRI* considered harmful Keith Thompson <kst-u@mib.org> - 2011-07-13 09:37 -0700
Re: PRI* considered harmful James Kuyper <jameskuyper@verizon.net> - 2011-07-09 06:46 -0400
Re: PRI* considered harmful Harald van Dijk <truedfx@gmail.com> - 2011-07-09 08:09 -0700
Re: PRI* considered harmful Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2011-07-11 16:00 +0300
Re: PRI* considered harmful Hans-Bernhard Bröker <HBBroeker@t-online.de> - 2011-07-09 20:59 +0200
Re: PRI* considered harmful Keith Thompson <kst-u@mib.org> - 2011-07-09 12:22 -0700
Re: PRI* considered harmful Hans-Bernhard Bröker <HBBroeker@t-online.de> - 2011-07-09 21:32 +0200
Re: PRI* considered harmful Keith Thompson <kst-u@mib.org> - 2011-07-09 12:54 -0700
Re: PRI* considered harmful Marcin Grzegorczyk <mgrzegor@poczta.onet.pl> - 2011-07-09 23:39 +0200
Re: PRI* considered harmful "Greg A. Woods" <woods@robohack.org> - 2011-07-09 16:56 -0700
Re: PRI* considered harmful "Greg A. Woods" <woods@robohack.org> - 2011-07-09 16:52 -0700
Re: PRI* considered harmful Keith Thompson <kst-u@mib.org> - 2011-07-09 18:53 -0700
Re: PRI* considered harmful Jens Gustedt <Jens.Gustedt@loria.fr> - 2011-07-10 14:12 +0200
Re: PRI* considered harmful Marcin Grzegorczyk <mgrzegor@poczta.onet.pl> - 2011-07-11 20:22 +0200
Re: PRI* considered harmful Jens Gustedt <Jens.Gustedt@loria.fr> - 2011-07-10 13:57 +0200
Re: PRI* considered harmful "Greg A. Woods" <woods@robohack.org> - 2011-07-09 16:49 -0700
Re: PRI* considered harmful Jens Schweikhardt <usenet@schweikhardt.net> - 2011-07-19 19:28 +0000
Re: PRI* considered harmful Tim Rentsch <txr@alumni.caltech.edu> - 2011-07-07 14:13 -0700
Re: PRI* considered harmful Keith Thompson <kst-u@mib.org> - 2011-07-09 01:04 -0700
Re: PRI* considered harmful "Greg A. Woods" <woods@robohack.org> - 2011-07-09 17:23 -0700
Re: PRI* considered harmful Keith Thompson <kst-u@mib.org> - 2011-07-09 19:03 -0700
Re: PRI* considered harmful Marcin Grzegorczyk <mgrzegor@poczta.onet.pl> - 2011-07-11 20:40 +0200
Re: PRI* considered harmful Keith Thompson <kst-u@mib.org> - 2011-07-11 11:56 -0700
Re: PRI* considered harmful Marcin Grzegorczyk <mgrzegor@poczta.onet.pl> - 2011-07-11 21:40 +0200
Re: PRI* considered harmful Keith Thompson <kst-u@mib.org> - 2011-07-11 13:16 -0700
Re: PRI* considered harmful Marcin Grzegorczyk <mgrzegor@poczta.onet.pl> - 2011-07-11 23:29 +0200
Re: PRI* considered harmful Keith Thompson <kst-u@mib.org> - 2011-07-11 14:46 -0700
Re: PRI* considered harmful "Greg A. Woods" <woods@robohack.org> - 2011-07-12 22:18 -0700
Re: PRI* considered harmful Keith Thompson <kst-u@mib.org> - 2011-07-13 09:00 -0700
Re: PRI* considered harmful Richard Kettlewell <rjk@greenend.org.uk> - 2011-07-09 20:30 +0100
csiph-web