size_t
is defined as an unsigned
integer, but the size of it depends on whether you're on a 32- or 64-bit machine. What's a correct and portable way to print out a size_t
?

- 1,561
- 3
- 11
- 27

- 13,683
- 10
- 38
- 36
-
4Possible duplicate of [Cross platform format string for variables of type size\_t?](http://stackoverflow.com/questions/174612/cross-platform-format-string-for-variables-of-type-size-t) – Ciro Santilli OurBigBook.com Oct 02 '15 at 09:31
-
1@CiroSantilli六四事件法轮功纳米比亚威视 I'm leaving it open because the duplicate contains some wrong answers whilst this one has one well-accepted answer. – edmz Oct 02 '15 at 17:41
-
@black you can also propose to close the other way. Either is fine for me. – Ciro Santilli OurBigBook.com Oct 02 '15 at 18:53
3 Answers
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
-
4size_t is an unsigned type so you still need to use 'u' as the format type as well as the 'z' length modifier. – CB Bailey Jun 02 '09 at 15:20
-
9Also, the 'z' modifier is a C99 addition to printf, so its not strictly a standard C++ feature. – CB Bailey Jun 02 '09 at 15:28
-
@Charles corrected the u portion and I added a C tag to the start. I would expect this to be much more a C feature than C++ as C++ can go the cout route. – JaredPar Jun 02 '09 at 15:48
-
3My compiler (gcc) gives warning: `unknown conversion type character 'z' in format [-Wformat]|`, and when the program runs it just prints `zu` as the output – lost_in_the_source Sep 01 '15 at 23:31
-
@JaredPar std::cout is only usable if you select the human language for outputs at compile time. The grammars of different languages force you to resort arguments when you want to use a different language. Well, you could use boost for type safe printf like features, but this also not strictly C++. – Keinstein Sep 06 '17 at 12:05
-
@Keinstein this doesn't mean that `printf` is a good option when localizing strings: a simple reordering of format specifiers (by a translator, to match the target grammar) can lead to undefined behavior when the types appear incompatible after the reordering. – Ruslan Oct 12 '17 at 13:15
-
2@Ruslan for that reason positional arguments have been introduced. See https://stackoverflow.com/questions/6322540/how-do-positional-arguments-like-1-work-with-printf . If they are used, your concern is not appicable. – Keinstein Oct 12 '17 at 14:35
-
On systems where `%zu` isn't supported, and it just prints out a literal `%zu` instead of the substituted value, I present various alternatives [in my answer here](https://stackoverflow.com/a/55943527/4561887). – Gabriel Staples Mar 20 '23 at 16:59
There's a C++ tag on this, so cout <<
is another possible answer.
This is surprisingly hard to get right in all versions of C. In C90, casting to unsigned long
should work, but that may well not work in C99, and the C99 solutions won't necessarily work in C90. The ability to reliably distinguish between C90 and C99 was introduced in the 1995 changes (specifying the allowable values for __STDC__
). I don't think there is a completely portable way that works for C90, C99, and C++, although there are solutions for any individual one of those.

- 56,304
- 9
- 91
- 158
I think that the C++ answer is:
std::size_t n = 1;
std::cout << n;
For C-style IO it's a little more complicated. In C99 they added the z
length modifier for size_t
values. However, previous to TR1 this is not supported so you are left with casting to a specific size like:
std::size_t n = 1;
std::printf("%lu\n", static_cast<unsigned long>(n));
Then again, unsigned long long
isn't really supported by C++ anyway so the above will work fine since unsigned long
is the largest legal integral type. After TR1 you can use %zu
safely for size_t
values.

- 58,213
- 10
- 98
- 113
-
How is unsigned long long not supported by C++? If you're basing it off the sizeof being the same on some platforms that's not the same thing as it not being supported. Mind you I had a very bad reaction to C++ (even besides I find it hideous) and I love C but I've not encountered a C++ compiler that doesn't support unsigned long long. And certainly it supports uint64_t. – Pryftan Dec 03 '19 at 15:25