tags:

views:

341

answers:

1

I was just looking through the man page for printf and something occurred to me. I was wondering if there are any "language lawyers" here which could answer a relatively simple question :-P.

So the 't' modifier is defined as

A following integer conversion corresponds to a ptrdiff_t argument.

So what is supposed to happen if you combine this with an unsigned integer conversion? Clearly o,u,x and X all all intended to be interpreted as unsigned values, while d and i are signed.

Likewise, there are signed/unsigned versions for all modifiers (int/unsigned int, size_t/ ssize_t, etc) except ptrdiff_t.

In practice, nothing bad happens since unsigned versions of types occupy the same amount of space as the signed versions. So the right about of bytes get popped off the stack.

So nothing "bad" happens, in fact, in prints the expected value for all things tested except the "INT_MIN" (assuming that sizeof(int) == sizeof(ptrdiff_t).

printf("%tu %td\n", INT_MIN, INT_MIN);

prints

2147483648 -2147483648

on a 32-bit system.

Does the standard have any opinion about this? I figure the answer will be "undefined behavior." But I figured I'd ask ;).

+3  A: 

Nothing to see here. The code you've written is legal.

Just some facts as to why:

  • all signed integer types have unsigned counterparts, with the same size/alignment requirements
  • ptrdiff_t is prescribed to be a signed integer type by the standard. Therefore, it has an unsigned twin. (In fact, similar logic applies to size_t as well - ssize_t is not C, but POSIX)
  • the t length specifier must work with d, i, o, u, x, X types
jpalecek
what is the valid unsigned equivalent to ptrdiff_t?
It has no special name - you can only say that if ptrdiff_t is "long long" then its unsigned counterpart is "unsigned long long" etc.
jpalecek