4 ms·
The C standards committee has been broken since C99 introduced long long, thus silently breaking conforming code. How do you print out a size_t, portably, with
by bhurt 15y ago
The C standards committee has been broken since C99 introduced long long, thus silently breaking conforming code.
How do you print out a size_t, portably, without losing information? The standard says size_t is an unsigned integer type, but doesn't say way size. However, the C89 spec explicitly stated that there are no integers sizes longer than long- so the conforming way to do this is to explicitly cast the size_t to unsigned long (which, while it may add bits, is guaranteed not to lose them), and print the unsigned long.
In an attempt to save all the broken, non-conforming code that assumed that sizeof(int) == sizeof(long), C99 introduced the long long type. And, among other things, allowed size_t to now be unsigned long long. Which meant the conforming C89 code that wants to print out a size_t is now wrong. Worse yet, it's silently broken- because the type cast is explicit, the compiler has to assume it's correct. They added a new way to print size_t's, granted- but this is no help for the legacy code (or code that needs to continue to support C89-only compilers).
Of course, the punchline here is that I have yet to see code that assumed sizeof(int) == sizeof(long) that didn't also assume sizeof(void *) == sizeof(int). So all that broken non-conforming code they were trying to save? It still needed to get fixed for 64-bit.
- phkamp 15y agoYou overlook the %z printf specifier which attempts, but not quite solves the problem, because size_t comes in both a signed (ssize_t) and unsigned (size_t) variant. I usually end up doing printf("%j", (intmax_t)foo);
- haberman 15y ago> because size_t comes in both a signed (ssize_t) and unsigned (size_t) variant. ssize_t is not ISO C. Also, %z is a modifier, not a specifier, so you can print size_t with %zu, or ssize_t with %zd.
- to3m 15y agoWon't "%zu" vs "%zd" do the trick? `z' is a modifier, like `l'. (That said, I've only ever used %zu myself... don't think I've ever used ssize_t. I'm pretty sure it's non-ISO.)
- caf 15y agoIt does (other variants like `%zx` are also fine).