Is the %zu specifier required for printf?
41,944
If size_t exists shouldn't zu also be available in printf?
size_t
existed at least since C89 but the respective format specifier %zu
(specifically the length modifier z
) was added to the standard only since C99.
So, if you can't use C99 (or C11) and had to print size_t
in C89, you just have to fallback to other existing types, such as:
printf("%lu\n", (unsigned long)n);
Comments
-
Trevor Hickey almost 2 years
We are using C89 on an embedded platform. I attempted to print out a
size_t
, but it did not work:#include <stdio.h> int main(void) { size_t n = 123; printf("%zu\n",n); return 0; }
Instead of
123
, I gotzu
.
Other specifiers work correctly.If
size_t
exists shouldn'tzu
also be available inprintf
?
Is this something I should contact my library vendor about, or is a library implementation allowed to exclude it?-
Kerrek SB over 7 yearsThe
z
prefix was added in C99 I believe. -
Trevor Hickey over 7 years@KerrekSB Ok. It doesn't seem to be annotated. en.cppreference.com/w/cpp/io/c/fprintf
-
mch over 7 yearsWhy should a C++ reference say anything about a C standard?
-
LPs over 7 yearsThe Man has it...
-
LPs over 7 years
-
Cubbi over 7 yearsNow marked on cppreference
-
Trevor Hickey over 7 years@mch Right. I meant to post the C reference.
-
-
supercat over 7 yearsNote that the above code would be sufficient, though not necessarily efficient, on any platform where
unsigned long
was large enough to accommodate the largest possible value ofn
(regardless of whether it was large enough to handle the full range ofsize_t
). There is no guarantee, however, thatsize_t
won't be larger thanunsigned long
, and there might not be any guarantee thatn
would always fit inunsigned long
. I don't know how often that would be a problem [many programs could run into different trouble if they calculate the size of sprintf buffers... -
supercat over 7 years...based upon a presumption that the maximum length of a decimal-formatted unsigned long is 10 digits and the value to be output ends up being longer than that].
-
chqrlie about 6 yearsFor better portability, use
printf("%llu\n", (unsigned long long)n);
, unless you know that the size is small, such assizeof(int)
in which case you can simply writeprintf("%u\n", (unsigned)n);
-
P.P over 5 years@chqrlie
unsigned long long
didn't exist in C89 - that's the reason I suggestedunsigned long
. Ifunsigned long long
is available (C99), then%zu
specifier forsize_t
would also be available. Thus there's no need to cast tounsigned long long
here at all. -
chqrlie over 5 yearsThe problem is actually located in the C library. A common case where
%zu
is not supported is older versions of MinGW that use gcc in combination with the system's Microsoft C library, which until very recently did not support most C99 extensions.