Is the %zu specifier required for printf?
Asked Answered
W

3

19

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 got zu.
Other specifiers work correctly.

If size_t exists shouldn't zu also be available in printf?
Is this something I should contact my library vendor about, or is a library implementation allowed to exclude it?

Wooer answered 21/12, 2016 at 13:27 Comment(7)
The z prefix was added in C99 I believe.Ferdelance
@KerrekSB Ok. It doesn't seem to be annotated. en.cppreference.com/w/cpp/io/c/fprintfWooer
Why should a C++ reference say anything about a C standard?Chaperon
The Man has it...Dellinger
Here a some historyDellinger
Now marked on cppreferenceEuplastic
@Chaperon Right. I meant to post the C reference.Wooer
O
30

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);
Otey answered 21/12, 2016 at 13:54 Comment(4)
Note 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 of n (regardless of whether it was large enough to handle the full range of size_t). There is no guarantee, however, that size_t won't be larger than unsigned long, and there might not be any guarantee that n would always fit in unsigned 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...Mehala
...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].Mehala
For better portability, use printf("%llu\n", (unsigned long long)n);, unless you know that the size is small, such as sizeof(int) in which case you can simply write printf("%u\n", (unsigned)n);Sessile
@Sessile unsigned long long didn't exist in C89 - that's the reason I suggested unsigned long. If unsigned long long is available (C99), then %zu specifier for size_t would also be available. Thus there's no need to cast to unsigned long long here at all.Otey
A
-4

size_t is returned by sizeof(). %zu specifier prints the length.So to return the size of n,the code should read: #include <stdio.h>

int main(void) { size_t n=123; printf("%zu\n",sizeof (n)); return 0;` }

Abrasive answered 9/9, 2020 at 6:11 Comment(0)
B
-10

This is working fine. In my system, it's printing the expected value. You may be getting the error due to the compiler. I am using the GCC compiler. If you have this only and trying to get the output the first update the GCC and then try. It will work.

Your program input

The output of the program

Beasley answered 30/3, 2018 at 5:26 Comment(1)
The 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.Sessile

© 2022 - 2024 — McMap. All rights reserved.