Thread View: comp.lang.c.moderated
11 messages
11 total messages
Started by Michael J Zehr
Thu, 14 Mar 1996 02:24
'h' modifier in printf
Author: Michael J Zehr
Date: Thu, 14 Mar 1996 02:24
Date: Thu, 14 Mar 1996 02:24
46 lines
1839 bytes
1839 bytes
I was recently asked a question about printf whose answer I couldn't
determine by reading K&R2 (and alas the company doesn't have a copy of
the standard to refer to).
The "h" modifier says the corresponding argument will be printed as a
short or unsigned short.
So, given:
short s;
printf("%d", s);
printf("%hd", s);
(Assuming of course that s has been initialized at some point.)
Can these two ever be different? I'm aware of course that the short is
widened to an int during the function call, but this preserves the
value.
(A totally non-relevant piece of information is that on at least one
platform there is never a difference between these two for any value of
s from SHRT_MIN to SHRT_MAX. But that doesn't answer the question.)
This is the main question I'm interested, but as a followup, if these
always result in the same output, why is the 'h' modifier defined in the
first place?
Some speculations:
int i;
printf("%hd", i);
printf("%d", (short)i);
This question is stretching a bit to try to find what if anything the
'h' modifier is ever used for. Certainly the first line would have a
different result without the 'h', but casting seems like it ought to
have the same result.
K&R2 is silent on whether "%hn" is valid as a conversion specifier. If
so, clearly this is a case in which the 'h' is absolutely required to
get the desired behavior.
Thanks,
michael j zehr
Re: 'h' modifier in printf
Author: baynes
Date: Thu, 14 Mar 1996 13:55
Date: Thu, 14 Mar 1996 13:55
77 lines
3573 bytes
3573 bytes
Michael J Zehr (tada@athena.mit.edu) wrote:
: I was recently asked a question about printf whose answer I couldn't
: determine by reading K&R2 (and alas the company doesn't have a copy of
: the standard to refer to).
>From the copy of the standard in Plauger's book:
"An optional h specifying that a following d, i, o, u, x or X conversion
specifier applies to a short int or unsigned short argument (the argument
will have been promoted according to the integral promotions, and its value
shall be converted to short in or unsigned short int before printing);..."
: The "h" modifier says the corresponding argument will be printed as a
: short or unsigned short.
: So, given:
: short s;
: printf("%d", s);
: printf("%hd", s);
: (Assuming of course that s has been initialized at some point.)
: Can these two ever be different? I'm aware of course that the short is
: widened to an int during the function call, but this preserves the
: value.
The should never be different.
: (A totally non-relevant piece of information is that on at least one
: platform there is never a difference between these two for any value of
: s from SHRT_MIN to SHRT_MAX. But that doesn't answer the question.)
Good.
: This is the main question I'm interested, but as a followup, if these
: always result in the same output, why is the 'h' modifier defined in the
: first place?
Probably so you can use the same format string with scanf.
: Some speculations:
: int i;
: printf("%hd", i);
: printf("%d", (short)i);
: This question is stretching a bit to try to find what if anything the
: 'h' modifier is ever used for. Certainly the first line would have a
: different result without the 'h', but casting seems like it ought to
: have the same result.
I think if the value of i is outside SHRT_MIN to SHRT_MAX then both are
undefined for different reasons. The first printf (%hd) because the conversion
does not apply to a short integer. The second printf (%d of (short)) because
the cast of i to (short) is not defined when i is out of range. If you had
used unsigned numbers and the u conversion then the second would become
defined because casting to a shorter unsigned number is defined, the first
would still be undefined. If i is in the range SHRT_MIN to SHRT_MAX you are
probably OK. However one could argue that a perverse implementation might
have some hidden means of detecting that the integer passed to printf was
actually taken from a short or an integer and then objecting in this case if
it did not come from as short as the standard specifies.
I understand different real implementations will behave differently if
the value passed to an 'h' modified conversion is out of range for the
appropriate short type.
'h' adds nothing useful over not using it, it just increases the potential
for undefined behaviour.
--
Stephen Baynes baynes@ukpsshp1.serigate.philips.nl
Philips Semiconductors Ltd
Southampton My views are my own.
United Kingdom
Re: 'h' modifier in printf
Author: T.E.Dickey
Date: Thu, 14 Mar 1996 14:20
Date: Thu, 14 Mar 1996 14:20
17 lines
1004 bytes
1004 bytes
Michael J Zehr (tada@athena.mit.edu) wrote:
: The "h" modifier says the corresponding argument will be printed as a
: short or unsigned short.
...
: short s;
: printf("%d", s);
: printf("%hd", s);
...
: Can these two ever be different? I'm aware of course that the short is
: widened to an int during the function call, but this preserves the
: value.
sure can -- you're overlooking sign extension
--
Thomas E. Dickey
dickey@clark.net
Re: 'h' modifier in printf
Author: Dan Pop
Date: Fri, 15 Mar 1996 03:14
Date: Fri, 15 Mar 1996 03:14
54 lines
1935 bytes
1935 bytes
In <4i801c$455@solutions.solon.com> tada@athena.mit.edu (Michael J Zehr) writes:
>The "h" modifier says the corresponding argument will be printed as a
>short or unsigned short.
>
>So, given:
>
>short s;
>printf("%d", s);
>printf("%hd", s);
>
>(Assuming of course that s has been initialized at some point.)
>
>Can these two ever be different?
No.
>This is the main question I'm interested, but as a followup, if these
>always result in the same output, why is the 'h' modifier defined in the
>first place?
Because there are other examples where the output is actually changed by
the 'h' modifier:
int i = SHRT_MAX + 1; /* assuming that INT_MAX > SHRT_MAX */
short s = -1;
printf("%d", i);
printf("%hd", i);
printf("%x", (unsigned)s);
printf("%hx", (unsigned)s);
>Some speculations:
>
>int i;
>printf("%hd", i);
>printf("%d", (short)i);
>
>This question is stretching a bit to try to find what if anything the
>'h' modifier is ever used for. Certainly the first line would have a
>different result without the 'h', but casting seems like it ought to
>have the same result.
You have just discovered that there's more than one way to achieve the
same result in C :-) The second method involves two conversions, while
the first one needs only one (inside printf).
Dan
--
Dan Pop
CERN, CN Division
Email: danpop@mail.cern.ch
Mail: CERN - PPE, Bat. 31 R-004, CH-1211 Geneve 23, Switzerland
Re: 'h' modifier in printf
Author: Dan Pop
Date: Fri, 15 Mar 1996 03:14
Date: Fri, 15 Mar 1996 03:14
24 lines
1218 bytes
1218 bytes
In <4i99vc$91r@solutions.solon.com> dickey@clark.net (T.E.Dickey) writes:
>Michael J Zehr (tada@athena.mit.edu) wrote:
>: The "h" modifier says the corresponding argument will be printed as a
>: short or unsigned short.
>...
>: short s;
>: printf("%d", s);
>: printf("%hd", s);
>...
>: Can these two ever be different? I'm aware of course that the short is
>: widened to an int during the function call, but this preserves the
>: value.
>sure can -- you're overlooking sign extension
How much time did you spent thinking, before posting this pearl of wisdom?
Dan
--
Dan Pop
CERN, CN Division
Email: danpop@mail.cern.ch
Mail: CERN - PPE, Bat. 31 R-004, CH-1211 Geneve 23, Switzerland
Re: 'h' modifier in printf
Author: Thad Smith
Date: Fri, 15 Mar 1996 03:23
Date: Fri, 15 Mar 1996 03:23
17 lines
1027 bytes
1027 bytes
In article <4i98fl$8ml@solutions.solon.com>,
baynes@ukpsshp1.serigate.philips.nl wrote:
>: int i;
>: printf("%hd", i);
>: printf("%d", (short)i);
>
>I think if the value of i is outside SHRT_MIN to SHRT_MAX then both are
>undefined for different reasons. The first printf (%hd) because the conversion
>does not apply to a short integer. The second printf (%d of (short)) because
>the cast of i to (short) is not defined when i is out of range.
Actually the result of the conversion in the second printf is
implementaion-defined.
Thad
Re: 'h' modifier in printf
Author: Gordon Burditt
Date: Sat, 16 Mar 1996 16:21
Date: Sat, 16 Mar 1996 16:21
29 lines
1112 bytes
1112 bytes
>The "h" modifier says the corresponding argument will be printed as a
>short or unsigned short.
>
>So, given:
>
>short s;
>printf("%d", s);
>printf("%hd", s);
>Can these two ever be different?
I don't think so, BUT:
short s = -1;
printf("%x\n", (unsigned int) s);
printf("%hx\n", (unsigned int) s);
/* is it allowed to leave out the casts? */
prints, on a machine with 16-bit shorts and 32-bit ints:
ffffffff
ffff
I believe this behavior in FreeBSD's gcc is correct, or at least allowed,
behavior for the given machine architecture. The h modifier isn't
totally useless, just mostly so.
Gordon L. Burditt
sneaky.lerctr.org!gordon
Re: 'h' modifier in printf
Author: Dan Pop
Date: Sun, 17 Mar 1996 03:17
Date: Sun, 17 Mar 1996 03:17
19 lines
1098 bytes
1098 bytes
In <4iepq6$af6@solutions.solon.com> gordon@sneaky.lerctr.org (Gordon Burditt) writes:
>I don't think so, BUT:
>short s = -1;
>printf("%x\n", (unsigned int) s);
>printf("%hx\n", (unsigned int) s);
>
>/* is it allowed to leave out the casts? */
In practice, yes (any int value is likely to have a meaning as unsigned
int as well and they have the same size). Strictly speaking, leaving out
the cast invokes undefined behaviour, however.
Dan
--
Dan Pop
CERN, CN Division
Email: danpop@mail.cern.ch
Mail: CERN - PPE, Bat. 31 R-004, CH-1211 Geneve 23, Switzerland
Re: 'h' modifier in printf
Author: Stan Ryckman
Date: Tue, 19 Mar 1996 12:47
Date: Tue, 19 Mar 1996 12:47
29 lines
1376 bytes
1376 bytes
In article <4i98fl$8ml@solutions.solon.com>, <baynes@ukpsshp1.serigate.philips.nl> wrote: >Michael J Zehr (tada@athena.mit.edu) wrote: [snip] >: This is the main question I'm interested, but as a followup, if these >: always result in the same output, why is the 'h' modifier defined in the >: first place? > >Probably so you can use the same format string with scanf. AVOID THIS ASSUMPTION!!! It's a common trap, and fails with floating point numbers. "%f" ==> output a double (*printf) "%f" ==> input a float (*scanf) IMHO, the format strings *should* have been designed so that the same one can be used to read back something written, but this is not the case. Sorry, they didn't ask me! :-) Cheers, Stan. -- Stan Ryckman (stanr@tiac.net) (Apologies for non-responses or late responses to some posts; .newsrc was trashed and I'm trying to get it back to where it was.)
Re: 'h' modifier in printf
Author: Holden P
Date: Sat, 23 Mar 1996 06:48
Date: Sat, 23 Mar 1996 06:48
37 lines
1419 bytes
1419 bytes
printf("Vanilla %X\nWith h %hX\n", -1, -1);
says
Vanilla FFFFFFFF
With h FFFF
In article <4i801c$455@solutions.solon.com>,
tada@athena.mit.edu (Michael J Zehr) writes:
>
>I was recently asked a question about printf whose answer I couldn't
>determine by reading K&R2 (and alas the company doesn't have a copy of
>the standard to refer to).
>
>The "h" modifier says the corresponding argument will be printed as a
>short or unsigned short.
>
>So, given:
>
>short s;
>printf("%d", s);
>printf("%hd", s);
>
>(Assuming of course that s has been initialized at some point.)
>
>Can these two ever be different? I'm aware of course that the short is
>widened to an int during the function call, but this preserves the
>value.
>
>
>Thanks,
>michael j zehr
--
Phil Holden: AKA holdp@essex.ac.uk Phone: +44 (0) 1206 872142
ESRC Data Archive, University of Essex, Colchester, Essex C04, 3SQ, U.K
Re: 'h' modifier in printf
Author: Dan Pop
Date: Mon, 25 Mar 1996 12:22
Date: Mon, 25 Mar 1996 12:22
20 lines
1046 bytes
1046 bytes
In <4j06rd$82n@solutions.solon.com> holdp@essex.ac.uk (Holden P) writes:
>printf("Vanilla %X\nWith h %hX\n", -1, -1);
>
>says
>
>Vanilla FFFFFFFF
>With h FFFF
Since the type of -1 is not unsigned int and it appears in a context where
the compiler is not required to perform the conversion, this example
invokes undefined behaviour, hence it cannot be used to demonstrate
anything.
Dan
--
Dan Pop
CERN, CN Division
Email: danpop@mail.cern.ch
Mail: CERN - PPE, Bat. 31 R-004, CH-1211 Geneve 23, Switzerland
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads