I often experience situations where I want to print with printf
the value of an integer type of implementation-defined size (like ino_t
or time_t
). Right now, I use a pattern like this for this:
#include <inttypes.h>
ino_t ino; /* variable of unknown size */
printf("%" PRIuMAX, (uintmax_t)ino);
This approach works so far but it has a couple of disadvantages:
- I have to know whether the type I'm trying print is signed or unsigned.
- I have to use a type cast that possibly enlarges my code.
Is there a better strategy?
Best Answer
That will certainly work (with some provisos; see below), but I'd use:
The
j
length modifierThere are also
z
andt
modifiers forsize_t
andptrdiff_t
(and their corresponding signed/unsigned types), respectively.And personally, I find the format string macros defined in
<inttypes.h>
ugly and difficult to remember, which is why I prefer"%ju"
or"%jd"
.As you mentioned, it's helpful to know whether the type (
ino_t
in this case) is signed or unsigned. If you don't happen to know that, it's possible to figure it out:though that may be overkill. If you're sure the type is narrower than 64 bits, you can convert the value to
intmax_t
, and the value will be preserved. Or you can useuintmax_t
and get well-defined results for all values, though printing-1
as18446744073709551615
(264-1) may be a bit confusing.All of this works only if your C implementation supports
<stdint.h>
and thej
length modifier forprintf
-- i.e., if it supports C99. Not all compilers do so (coughMicrosoftcough). For C90, the widest integer types arelong
andunsigned long
, and you can convert to those and use"%ld"
and/or"%lu"
. You can theoretically test for C99 compliance using the__STDC_VERSION__
predefined macro -- though some pre-C99 compilers might still support types wider thanlong
andunsigned long
as an extension.