How can one print a size_t variable portably using the printf family?
Use the z
modifier:
size_t x = ...;
ssize_t y = ...;
printf("%zu\n", x); // prints as unsigned decimal
printf("%zx\n", x); // prints as hex
printf("%zd\n", y); // prints as signed decimal
What's the correct way to use printf to print a size_t?
Try using the %zu
format string
size_t val = get_the_value();
printf("%zu",val);
The z portion is a length specifier which says the argument will be size_t in length.
Source - http://en.wikipedia.org/wiki/Printf#printf_format_placeholders
How should I print types like off_t and size_t?
You can use z
for size_t and t
for ptrdiff_t like in
printf("%zu %td", size, ptrdiff);
But my manpage says some older library used a different character than z
and discourages use of it. Nevertheless, it's standardized (by the C99 standard). For those intmax_t
and int8_t
of stdint.h
and so on, there are macros you can use, like another answer said:
printf("value: %" PRId32, some_int32_t);
printf("value: %" PRIu16, some_uint16_t);
They are listed in the manpage of inttypes.h
.
Personally, I would just cast the values to unsigned long
or long
like another answer recommends. If you use C99, then you can (and should, of course) cast to unsigned long long
or long long
and use the %llu
or %lld
formats respectively.
How to print size_t and ptrdiff_t using printf in ANSI C (C89)
size_t
is an implementation-defined unsigned integer type. ptrdiff_t
is an implementation-defined signed integer type.
In C89/C90 (commonly, but strictly speaking incorrectly, referred to as "ANSI C"), there are no special format specifiers for these types. But the widest integer types are long int
and unsigned long int
, which of course do have their own format specifiers.
To print a size_t
value, cast it to unsigned long
and use "%lu"
.
To print a ptrdiff_t
value, cast it to long
and use "%ld"
.
Note that if your code is then compiled with a C99 or C11 compiler, it's possible that size_t
and/or ptrdiff_t
could be wider than long
, and the code could fail. (As I recall the 64-bit Windows interface has 32-bit long
, so that could be an issue in practice.)
In C99 and later, just use %zu
for size_t
and %td
for ptrdiff_t
. If you want your code to be really portable, consider using #if
to test the value of __STDC_VERSION__
.
You could also run into problems if you have a compiler that only partially conforms to C99 or C11. You might have a compiler that doesn't fully support C99, but that does provide long long
. But for the purpose of printing a size_t
value, that's only going to be an issue if the value you're printing actually exceeds ULONG_MAX
, which is at least 232-1. For a ptrdiff_t
value, converting to long
is OK as long as it doesn't exceed LONG_MAX
, which is at least 231-1.
Finally, if you happen to know that the values you're printing aren't too big, you can get away with casting to int
and using %d
. I recommend casting to unsigned long
or long
, but int
is OK for quick-and-dirty code.
What about using the
p
specifier?
No, %p
is only for pointers of type void*
, and in any case the output format is implementation-defined (it's commonly hex, but I've seen other representations).
Correct printf format specifier for size_t: %zu or %Iu?
MS Visual Studio didn't support %zu
printf specifier before VS2013
. Starting from VS2013 (e.g. _MSC_VER
>= 1800
) %zu
is available.
As an alternative, for previous versions of Visual Studio if you are printing small values (like number of elements from std containers) you can simply cast to an int
and use %d
:
printf("count: %d\n", (int)str.size()); // less digital ink spent
// or:
printf("count: %u\n", (unsigned)str.size());
printf format specifiers for uint32_t and size_t
Sounds like you're expecting size_t
to be the same as unsigned long
(possibly 64 bits) when it's actually an unsigned int
(32 bits). Try using %zu
in both cases.
I'm not entirely certain though.
Printing size_t using printf in GNU systems
The question as asked:
Does really the 1989 Standard C allow that code?
Yes, if by "allow" we mean "this will compile and run, doing something reasonable and not triggering undefined behavior" (and not "this will do what I want"). The two cases are slightly different.
For size_t
, the result will be truncated if it is too large. For ptrdiff_t
, the result will be implementation-defined if it is too large.
However, recent versions of Visual Studio (_MSC_VER >= 1800
) support the z
and t
conversions (necessary for C++11 support anyway), so you can use:
size_t size;
printf("size = %zu\n", size);
ptrdiff_t diff;
printf("diff = %td\n", diff);
This will also work on other systems (GNU, BSD, Darwin). For older versions of Visual Studio there are alternatives, but it would require using a different format string on different platforms.
A note on GNU coding standards
The GNU coding standards are for the GNU organization, which has some very specific goals and does not care much about supporting Windows. I would take their coding standards with a grain of salt, unless you have a specific reason to follow them (for example, you want your project to become a GNU project in the future).
Clean code to printf size_t in C++ (or: Nearest equivalent of C99's %z in C++)
Most compilers have their own specifier for size_t
and ptrdiff_t
arguments, Visual C++ for instance use %Iu and %Id respectively, I think that gcc will allow you to use %zu and %zd.
You could create a macro:
#if defined(_MSC_VER) || defined(__MINGW32__) //__MINGW32__ should goes before __GNUC__
#define JL_SIZE_T_SPECIFIER "%Iu"
#define JL_SSIZE_T_SPECIFIER "%Id"
#define JL_PTRDIFF_T_SPECIFIER "%Id"
#elif defined(__GNUC__)
#define JL_SIZE_T_SPECIFIER "%zu"
#define JL_SSIZE_T_SPECIFIER "%zd"
#define JL_PTRDIFF_T_SPECIFIER "%zd"
#else
// TODO figure out which to use.
#if NUMBITS == 32
#define JL_SIZE_T_SPECIFIER something_unsigned
#define JL_SSIZE_T_SPECIFIER something_signed
#define JL_PTRDIFF_T_SPECIFIER something_signed
#else
#define JL_SIZE_T_SPECIFIER something_bigger_unsigned
#define JL_SSIZE_T_SPECIFIER something_bigger_signed
#define JL_PTRDIFF_T_SPECIFIER something-bigger_signed
#endif
#endif
Usage:
size_t a;
printf(JL_SIZE_T_SPECIFIER, a);
printf("The size of a is " JL_SIZE_T_SPECIFIER " bytes", a);
Related Topics
Order of Evaluation in C++ Function Parameters
How to Remove Code Duplication Between Similar Const and Non-Const Member Functions
Derived Template-Class Access to Base-Class Member-Data
Thou Shalt Not Inherit from Std::Vector
How to Enable C++11/C++0X Support in Eclipse Cdt
How to Reverse a String in Place in C or C++
In Which Scenario Do I Use a Particular Stl Container
Problems Importing Libraries to My C++ Project, How to Fix This
What Platforms Have Something Other Than 8-Bit Char
What Do Single Quotes Do in C++ When Used on Multiple Characters
How to Convert a Std::String to Int
Exotic Architectures the Standards Committees Care About
How to Figure Out the Parameter Type and Return Type of a Lambda
What Happens If I Define a 0-Size Array in C/C++
Use of 'Const' For Function Parameters
C++ Convert Hex String to Signed Integer
How to Take Input to an Array With Unknown Number of Elements