?
The man page for printf on my system recommends hh modifier to print
integer value of a character. If you use %c then this will display it as
an ASCII character.
Obviously several people (me too) learned something new from this but
it seems there is no benefit from the modifier (yes, hh is a single
modifier). Furthermore, using it can lead to unexpected behavior.
First, let's eliminate the easy case. I don't see a use for %hhn (or
%hn) but the intent is clear. It will allow you to store the
character count into one of the lower ranking (and presumably shorter)
integer types. Maybe this is useful on an imbedded system with
extremely limited memory but would such a system even have a printf
function?
Second, you are passing a char (which will be converted to an int
before it is received). If the value is within the range of a signed
char, the value will be unchanged when printf converts it to signed
char. Printing this value will result in the exact same character
sequence by both %hhd and %d. Nothing is gained in this case. In the
case where char is unsigned, printf will still try to convert the
value back to a signed char. If the value does not fit, the next
paragraph applies.
But when a signed value (int or short) is passed that is not within
the range of signed char, printf's attempt to convert it to signed
char falls under the purview of 6.3.1.3-3.
In summary:
Since 255 is not a particularly long text sequence, %hhn is as
inherently unsafe as gets().
65,535 is probably adequate for most writes so an overflow with
%hn would be surprising.
Using %hhd or %hhi on anything other than a signed char puts the
program at risk and using it for a signed char does not provide any
benefit.
A similar situation holds for %hd and %hi. Using either with an
int or unsigned short value that does not fit in a signed short is
undesirable. If the value does fit, there is no benefit.
Slightly unrelated but can someone explain why converting an out of
range real floating value to integer produces undefined behavior but
doing the same to an out of range integer value produces "merely"
implementation defined behavior.