By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
449,208 Members | 1,845 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 449,208 IT Pros & Developers. It's quick & easy.

Print a short instead of an int... ? What's up with "%hd"?

P: n/a

When passing arguments to a VAL function, all integer types are
promoted, and floats become doubles. Therefore, signed short will be
promoted to signed int. Therefore I can't see any reason why you'd
have:

printf( "%hd", my_short);

instead of:

printf( "%d", my_short);
Martin

Oct 22 '07 #1
Share this Question
Share on Google+
17 Replies


P: n/a
Martin Wells wrote:
When passing arguments to a VAL function, all integer types are
promoted, and floats become doubles. Therefore, signed short will be
promoted to signed int. Therefore I can't see any reason why you'd
have:

printf( "%hd", my_short);

instead of:

printf( "%d", my_short);
I believe that the purpose is to allow the use of the same format string
for printf() and scanf(). The 'h' adds nothing during the printing
process, but makes a difference in the scanning process.
Oct 22 '07 #2

P: n/a
"James Kuyper Jr." wrote:
>
Martin Wells wrote:
When passing arguments to a VAL function, all integer types are
promoted, and floats become doubles. Therefore, signed short will be
promoted to signed int. Therefore I can't see any reason why you'd
have:

printf( "%hd", my_short);

instead of:

printf( "%d", my_short);

I believe that the purpose is to allow the use of the same format string
for printf() and scanf(). The 'h' adds nothing during the printing
process, but makes a difference in the scanning process.
It could make a difference. Consider "%hx" when passed (short)-1,
which on my system prints "ffff", whereas "%x" prints "ffffffff".

--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h|
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:Th*************@gmail.com>

Oct 22 '07 #3

P: n/a
Kenneth:
It could make a difference. Consider "%hx" when passed (short)-1,
which on my system prints "ffff", whereas "%x" prints "ffffffff".

OK I can see how the following are true:

(unsigned)(short)-1 == UINT_MAX (maybe 0xffff)
(short unsigned)(short)-1 == USHRT_MAX (maybe 0xffffffff)

....but is it not undefined behaviour to supply printf with a signed
integer type when it expects an unsigned integer type, or vice versa?

If I wanted to print the max value of an unsigned short (without using
USHRT_MAX of course), then I'd go with:

printf("%u",(unsigned)(short unsigned)-1)

Martin

Oct 22 '07 #4

P: n/a
On Oct 23, 3:32 am, Kenneth Brody <kenbr...@spamcop.netwrote:
"James Kuyper Jr." wrote:
I believe that the purpose is to allow the use of the same format string
for printf() and scanf(). The 'h' adds nothing during the printing
process, but makes a difference in the scanning process.

It could make a difference. Consider "%hx" when passed (short)-1,
which on my system prints "ffff", whereas "%x" prints "ffffffff".
Well, you caused undefined behaviour by passing a
signed value. James' comment should be read as saying
it makes no difference to conforming code!

The %hx could in theory allow the compiler to optimize
more, as the printf implementation has the option of
discarding 2 of the 4 bytes read (say) before processing
them.

Oct 23 '07 #5

P: n/a
Old Wolf wrote:
>
On Oct 23, 3:32 am, Kenneth Brody <kenbr...@spamcop.netwrote:
"James Kuyper Jr." wrote:
I believe that the purpose is to allow the use of the same format string
for printf() and scanf(). The 'h' adds nothing during the printing
process, but makes a difference in the scanning process.
It could make a difference. Consider "%hx" when passed (short)-1,
which on my system prints "ffff", whereas "%x" prints "ffffffff".

Well, you caused undefined behaviour by passing a
signed value. James' comment should be read as saying
it makes no difference to conforming code!
You are, of course, correct. I hadn't thought about it before,
but it makes perfect sense that %x takes an unsigned value.
(After all, I would want something like "8000" to display, and
not "-7fff".)
The %hx could in theory allow the compiler to optimize
more, as the printf implementation has the option of
discarding 2 of the 4 bytes read (say) before processing
them.
What does the standard say about a varadic function which gets
passed an int but reads it as short? Given that the standard
requires that (in this instance) a short be promoted to int
anyway, does passing an int invoke UB?

On a system with 16-bit short and 32-bit int, does this invoke
UB?

printf("%hd\n",65536);

My system displays zero, but "gives you the output you expect"
is allowed under UB. :-)

Section 7.19.6.1p7 seems to allow it:

h Specifies that a following d, i, o, u, x, or X conversion
specifier applies to a short int or unsigned short int
argument (the argument will have been promoted according
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
to the integer promotions, but its value shall be
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
converted to short int or unsigned short int before
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^
printing); or that a following n conversion specifier
^^^^^^^^
applies to a pointer to a short int argument.

--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h|
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:Th*************@gmail.com>
Oct 23 '07 #6

P: n/a
On Oct 24, 3:04 am, Kenneth Brody <kenbr...@spamcop.netwrote:
On a system with 16-bit short and 32-bit int, does this invoke
UB?

printf("%hd\n",65536);
I would think so, but a more interesting question
is whether this invokes UB:
printf("%hd\n", 0);

We've had this discussion at least once before (in
fact, I initiated it one time). I don't recall the
conclusion however :)

Oct 23 '07 #7

P: n/a
In article <11**********************@q5g2000prf.googlegroups. comOld Wolf <ol*****@inspire.net.nzwrites:
On Oct 23, 3:32 am, Kenneth Brody <kenbr...@spamcop.netwrote:
....
It could make a difference. Consider "%hx" when passed (short)-1,
which on my system prints "ffff", whereas "%x" prints "ffffffff".

Well, you caused undefined behaviour by passing a
signed value. James' comment should be read as saying
it makes no difference to conforming code!
Yes, even (unsigned short)2 passed for "%hx" causes undefined behaviour,
when int and short are not essentially the same. So when passing
an "unsigned short", you should cast it to an "unsigned int". Ah, I
like those integer promotion rules. The only arguments types you can
reliably pass to "%x" are unsigned int and longer.
--
dik t. winter, cwi, kruislaan 413, 1098 sj amsterdam, nederland, +31205924131
home: bovenover 215, 1025 jn amsterdam, nederland; http://www.cwi.nl/~dik/
Oct 24 '07 #8

P: n/a
Dik T. Winter wrote:
The only arguments types you can
reliably pass to "%x" are unsigned int and longer.
What is reliable about using a longer type than unsigned,
with "%x"?

--
pete
Oct 24 '07 #9

P: n/a
"Dik T. Winter" <Di********@cwi.nla écrit dans le message de news:
Jq********@cwi.nl...
In article <11**********************@q5g2000prf.googlegroups. comOld Wolf
<ol*****@inspire.net.nzwrites:
On Oct 23, 3:32 am, Kenneth Brody <kenbr...@spamcop.netwrote:
...
It could make a difference. Consider "%hx" when passed (short)-1,
which on my system prints "ffff", whereas "%x" prints "ffffffff".
Well, you caused undefined behaviour by passing a
signed value. James' comment should be read as saying
it makes no difference to conforming code!

Yes, even (unsigned short)2 passed for "%hx" causes undefined behaviour,
when int and short are not essentially the same. So when passing
an "unsigned short", you should cast it to an "unsigned int". Ah, I
like those integer promotion rules. The only arguments types you can
reliably pass to "%x" are unsigned int and longer.
It may well be the case under the current wording of the standard, but I
cannot believe it be the intent of the Commitee. It would take an
inordinate amount of bad faith to come up with an implementation that shows
unexpected behaviour for such a case. It would cause enough portability
problems for so many programs to be adequately qualified as *broken*. There
is nothing wrong with passing an int or shorter type for %x format. Passing
anything larger (or longer) is wrong.

--
Chqrlie.
Oct 26 '07 #10

P: n/a
On Fri, 26 Oct 2007 06:49:36 +0200, Charlie Gordon wrote:
"Dik T. Winter" <Di********@cwi.nla écrit dans le message de news:
Jq********@cwi.nl...
>Yes, even (unsigned short)2 passed for "%hx" causes undefined
behaviour, when int and short are not essentially the same. So when
passing an "unsigned short", you should cast it to an "unsigned int".
Ah, I like those integer promotion rules. The only arguments types you
can reliably pass to "%x" are unsigned int and longer.

It may well be the case under the current wording of the standard, but I
cannot believe it be the intent of the Commitee.
That's not what the current wording of the standard says, and like you I
would be extremely surprised if it actually turned out to be the intent.
%hx accepts an argument of whatever type unsigned short promotes to. This
will be signed int on some implementations, and unsigned on others, but
(unsigned short)2 will be a valid argument on all implementations.
Oct 26 '07 #11

P: n/a
In article <ff**********@news5.zwoll1.ov.home.nl=?iso-2022-kr?q?=1B=24=29CHarald_van_D=0E=29=26=0Fk?= <tr*****@gmail.comwrites:
On Fri, 26 Oct 2007 06:49:36 +0200, Charlie Gordon wrote:
"Dik T. Winter" <Di********@cwi.nla écrit dans le message de news:
Jq********@cwi.nl...
Yes, even (unsigned short)2 passed for "%hx" causes undefined
behaviour, when int and short are not essentially the same. So when
passing an "unsigned short", you should cast it to an "unsigned int".
Ah, I like those integer promotion rules. The only arguments types you
can reliably pass to "%x" are unsigned int and longer.
....
That's not what the current wording of the standard says, and like you I
would be extremely surprised if it actually turned out to be the intent.
%hx accepts an argument of whatever type unsigned short promotes to.
In the draft version of the standard I have, section 7.19.6.1, par 3:
o,u,x,X The *unsigned int* argument is converted to unsigned octal (o),
...

--
dik t. winter, cwi, kruislaan 413, 1098 sj amsterdam, nederland, +31205924131
home: bovenover 215, 1025 jn amsterdam, nederland; http://www.cwi.nl/~dik/
Oct 29 '07 #12

P: n/a
On Oct 28, 7:25 pm, "Dik T. Winter" <Dik.Win...@cwi.nlwrote:
In article <fft873$vd...@news5.zwoll1.ov.home.nl=?iso-2022-kr?q?=1B=24=29CHarald_van_D=0E=29=26=0Fk?= <true...@gmail.comwrites:
On Fri, 26 Oct 2007 06:49:36 +0200, Charlie Gordon wrote:
"Dik T. Winter" <Dik.Win...@cwi.nla écrit dans le message de news:
JqE7D0....@cwi.nl...
Yes, even (unsigned short)2 passed for "%hx" causes undefined
behaviour, when int and short are not essentially the same. So when
passing an "unsigned short", you should cast it to an "unsigned int".
Ah, I like those integer promotion rules. The only arguments typesyou
can reliably pass to "%x" are unsigned int and longer.
...
That's not what the current wording of the standard says, and like youI
would be extremely surprised if it actually turned out to be the intent.
%hx accepts an argument of whatever type unsigned short promotes to.

In the draft version of the standard I have, section 7.19.6.1, par 3:
o,u,x,X The *unsigned int* argument is converted to unsigned octal (o),
...
h Specifies that a following d, i, o, u, x, or X conversion
specifier
applies to a short int or unsigned short int argument (the
argument
will have been promoted according to the integer promotions,
but its
value shall be converted to a short int or unsigned short int
before
printing)

Oct 29 '07 #13

P: n/a
On Oct 28, 8:08 pm, Justin Spahr-Summers
<Justin.SpahrSumm...@gmail.comwrote:
On Oct 28, 7:25 pm, "Dik T. Winter" <Dik.Win...@cwi.nlwrote:
In article <fft873$vd...@news5.zwoll1.ov.home.nl=?iso-2022-kr?q?=1B=24=29CHarald_van_D=0E=29=26=0Fk?= <true...@gmail.comwrites:
On Fri, 26 Oct 2007 06:49:36 +0200, Charlie Gordon wrote:
"Dik T. Winter" <Dik.Win...@cwi.nla écrit dans le message de news:
JqE7D0....@cwi.nl...
Yes, even (unsigned short)2 passed for "%hx" causes undefined
behaviour, when int and short are not essentially the same. So when
passing an "unsigned short", you should cast it to an "unsigned int".
Ah, I like those integer promotion rules. The only arguments types you
can reliably pass to "%x" are unsigned int and longer.
...
That's not what the current wording of the standard says, and like you I
would be extremely surprised if it actually turned out to be the intent.
%hx accepts an argument of whatever type unsigned short promotes to.
In the draft version of the standard I have, section 7.19.6.1, par 3:
o,u,x,X The *unsigned int* argument is converted to unsigned octal (o),
...

h Specifies that a following d, i, o, u, x, or X conversion
specifier
applies to a short int or unsigned short int argument (the
argument
will have been promoted according to the integer promotions,
but its
value shall be converted to a short int or unsigned short int
before
printing)
Ick. I thought I wrapped it to the right length. Apparently not.

Oct 29 '07 #14

P: n/a
"Dik T. Winter" wrote:
>
.... snip ...
>
>That's not what the current wording of the standard says, and like
you I would be extremely surprised if it actually turned out to be
the intent. %hx accepts an argument of whatever type unsigned short
promotes to.

In the draft version of the standard I have, section 7.19.6.1, par 3:
o,u,x,X The *unsigned int* argument is converted to unsigned octal
(o), ...
I think you meant para. 8.

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>

--
Posted via a free Usenet account from http://www.teranews.com

Oct 29 '07 #15

P: n/a
Dik T. Winter wrote:
>
In article <ff**********@news5.zwoll1.ov.home.nl=?iso-2022-kr?q?=1B=24=29CHarald_van_D=0E=29=26=0Fk?= <tr*****@gmail.comwrites:
On Fri, 26 Oct 2007 06:49:36 +0200, Charlie Gordon wrote:
"Dik T. Winter" <Di********@cwi.nl>
a écrit dans le message de news:
Jq********@cwi.nl...
The only arguments types you
can reliably pass to "%x" are unsigned int and longer.
In the draft version of the standard I have, section 7.19.6.1, par 3:
o,u,x,X The *unsigned int*
argument is converted to unsigned octal (o), ...
I still don't see where you're getting "and longer" from.

--
pete
Oct 29 '07 #16

P: n/a
In article <11**********************@19g2000hsx.googlegroups. comJustin Spahr-Summers <Ju*****************@gmail.comwrites:
On Oct 28, 7:25 pm, "Dik T. Winter" <Dik.Win...@cwi.nlwrote:
....
In the draft version of the standard I have, section 7.19.6.1, par 3:
o,u,x,X The *unsigned int* argument is converted to unsigned octal (o),
...

h Specifies that a following d, i, o, u, x, or X conversion specifier
applies to a short int or unsigned short int argument (the argument
will have been promoted according to the integer promotions, but its
value shall be converted to a short int or unsigned short int before
printing)
Indeed. But what is the 'x' doing if the argument is a signed int?
Suppose we have: %hd and (unsigned short)2 as argument. The argument is
promoted to int. 'h' specifies that the argument was short or unsigned
short before promotion, and that the argument will be converted to short
or unsigned short (to what? how does printf know whether the actual argument
was a short or an unsigned short before promotion?). But now 'x' does not
specify what is happening, because it only specifies what is happening when
the argument after promotion is an unsigned int. BTW, this means that also
%lx is actually undefined.

--
dik t. winter, cwi, kruislaan 413, 1098 sj amsterdam, nederland, +31205924131
home: bovenover 215, 1025 jn amsterdam, nederland; http://www.cwi.nl/~dik/
Oct 31 '07 #17

P: n/a
In article <47**********@mindspring.compf*****@mindspring.com writes:
Dik T. Winter wrote:

In article <ff**********@news5.zwoll1.ov.home.nl=?iso-2022-kr?q?=1B=24=29CHarald_van_D=0E=29=26=0Fk?= <tr*****@gmail.comwrites:
On Fri, 26 Oct 2007 06:49:36 +0200, Charlie Gordon wrote:
"Dik T. Winter" <Di********@cwi.nl>
a écrit dans le message de news:
Jq********@cwi.nl...
The only arguments types you
can reliably pass to "%x" are unsigned int and longer.
In the draft version of the standard I have, section 7.19.6.1, par 3:
o,u,x,X The *unsigned int*
argument is converted to unsigned octal (o), ...

I still don't see where you're getting "and longer" from.
Indeed, that was an error.
--
dik t. winter, cwi, kruislaan 413, 1098 sj amsterdam, nederland, +31205924131
home: bovenover 215, 1025 jn amsterdam, nederland; http://www.cwi.nl/~dik/
Oct 31 '07 #18

This discussion thread is closed

Replies have been disabled for this discussion.