I'm trying to print types like off_t
and size_t
. What is the correct placeholder for printf()
that is portable?
Or is there a completely different way to print those variables?
This question is related to
c
portability
format-specifiers
You'll want to use the formatting macros from inttypes.h.
See this question: Cross platform format string for variables of type size_t?
As I recall, the only portable way to do it, is to cast the result to "unsigned long int" and use %lu
.
printf("sizeof(int) = %lu", (unsigned long) sizeof(int));
To print off_t
:
printf("%jd\n", (intmax_t)x);
To print size_t
:
printf("%zu\n", x);
To print ssize_t
:
printf("%zd\n", x);
See 7.19.6.1/7 in the C99 standard, or the more convenient POSIX documentation of formatting codes:
http://pubs.opengroup.org/onlinepubs/009695399/functions/fprintf.html
If your implementation doesn't support those formatting codes (for example because you're on C89), then you have a bit of a problem since AFAIK there aren't integer types in C89 that have formatting codes and are guaranteed to be as big as these types. So you need to do something implementation-specific.
For example if your compiler has long long
and your standard library supports %lld
, you can confidently expect that will serve in place of intmax_t
. But if it doesn't, you'll have to fall back to long
, which would fail on some other implementations because it's too small.
Looking at man 3 printf
on Linux, OS X, and OpenBSD all show support for %z
for size_t
and %t
for ptrdiff_t
(for C99), but none of those mention off_t
. Suggestions in the wild usually offer up the %u
conversion for off_t
, which is "correct enough" as far as I can tell (both unsigned int
and off_t
vary identically between 64-bit and 32-bit systems).
I saw this post at least twice, because the accepted answer is hard to remeber for me(I rarely use z
or j
flags and they are seems not platform independant).
The standard never says clearly the exact data length of size_t
, so I suggest you should first check the length size_t
on your platform then select one of them:
if sizeof(size_t) == 4 use PRIu32
if sizeof(size_t) == 8 use PRIu64
And I suggest using stdint
types instead of raw data types for consistancy.
For Microsoft, the answer is different. VS2013 is largely C99 compliant but "[t]he hh, j, z, and t length prefixes are not supported." For size_t "that is, unsigned __int32 on 32-bit platforms, unsigned __int64 on 64-bit platforms" use prefix I (capital eye) with type specifier o, u, x, or X. See VS2013 Size specification
As for off_t, it is defined as long in VC\include\sys\types.h.
use "%zo" for off_t. (octal) or "%zu" for decimal.
Which version of C are you using?
In C90, the standard practice is to cast to signed or unsigned long, as appropriate, and print accordingly. I've seen %z for size_t, but Harbison and Steele don't mention it under printf(), and in any case that wouldn't help you with ptrdiff_t or whatever.
In C99, the various _t types come with their own printf macros, so something like "Size is " FOO " bytes."
I don't know details, but that's part of a fairly large numeric format include file.
Source: Stackoverflow.com