17

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?

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
Trevor Hickey
  • 36,288
  • 32
  • 162
  • 271

3 Answers3

26

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);
P.P
  • 117,907
  • 20
  • 175
  • 238
  • 1
    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... – supercat Dec 27 '16 at 19:26
  • ...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]. – supercat Dec 27 '16 at 19:27
  • 1
    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);` – chqrlie Mar 30 '18 at 10:03
  • 3
    @chqrlie `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. – P.P Sep 24 '18 at 08:10
-5

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;` }

-9

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

Faysal Ahmed
  • 7,501
  • 5
  • 28
  • 50
  • 2
    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. – chqrlie Sep 24 '18 at 20:23