468,505 Members | 1,938 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 468,505 developers. It's quick & easy.

Why do they cast it twice?

Hi, I've browsed the STL code a bit and stumble upon the next line (in
the operator << overload of both long and short outputs - the line is
for checking does the input is a manipulator)

long _Tmp = (_Bfl == ios_base::oct || _Bfl == ios_base::hex)
? (long)(unsigned short)_Val //<-This Line
: (long)_Val;

Is there any profound reason why they "Double" casting the _Val?
Thanks.
Mar 30 '08 #1
8 4725
On 30 mar, 10:06, ManicQin <Manic...@gmail.comwrote:
Hi, I've browsed the STL code a bit and stumble upon the next line (in
the operator << overload of both long and short outputs - the line is
for checking does the input is a manipulator)
long _Tmp = (_Bfl == ios_base::oct || _Bfl == ios_base::hex)
? (long)(unsigned short)_Val //<-This Line
: (long)_Val;
Is there any profound reason why they "Double" casting the _Val?
Not knowing the type of _Val, I can't say, but in general,
casting through an unsigned type guarantees a positive value in
the long (unless the positive value won't fit).

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Mar 30 '08 #2
ManicQin wrote:
Hi, I've browsed the STL code a bit and stumble upon the next line
(in the operator << overload of both long and short outputs - the
line is for checking does the input is a manipulator)

long _Tmp = (_Bfl == ios_base::oct || _Bfl == ios_base::hex)
? (long)(unsigned short)_Val //<-This Line
: (long)_Val;

Is there any profound reason why they "Double" casting the _Val?
Thanks.
Yes, the idea is to get the value unsigned, to avoid sign extension
for hex and octal representation.
Bo Persson
Mar 30 '08 #3
>Not knowing the type of _Val, I can't say, but in general,
>casting through an unsigned type guarantees a positive value in
the long (unless the positive value won't fit).
The same behavior returns when _Val is long and short.
Yes, the idea is to get the value unsigned, to avoid sign extension
for hex and octal representation.
So why not just cast it directly to unsigned long... why the DOUBLE
cast...
I'm referring to the line (long)(unsigned short)_Val
besides ... when casting to unsigned and then to signed isn't the
result will be signed again?

(AFAIK long is synonymous with signed long int)
Mar 30 '08 #4
ManicQin wrote:
>Not knowing the type of _Val, I can't say, but in general,
casting through an unsigned type guarantees a positive value in
the long (unless the positive value won't fit).

The same behavior returns when _Val is long and short.
>Yes, the idea is to get the value unsigned, to avoid sign extension
for hex and octal representation.

So why not just cast it directly to unsigned long... why the DOUBLE
cast...
I'm referring to the line (long)(unsigned short)_Val
besides ... when casting to unsigned and then to signed isn't the
result will be signed again?
It will not be the same if the short value is negative.
Bo Persson

Mar 30 '08 #5
ManicQin <Ma******@gmail.comwrote:
Hi, I've browsed the STL code a bit and stumble upon the next line (in
the operator << overload of both long and short outputs - the line is
for checking does the input is a manipulator)

long _Tmp = (_Bfl == ios_base::oct || _Bfl == ios_base::hex)
? (long)(unsigned short)_Val //<-This Line
: (long)_Val;

Is there any profound reason why they "Double" casting the _Val?
Thanks.
Let's pretend that _Val is a short and sizeof(short) is 2 and
sizeof(long) is 4...

If _Bfl == oct or hex, and _Val == 0xFFFF (-1), then _Val will be cast
to (unsigned short)0xFFFF (65535) and then to (long)0xFFFF (65535).

whereas if _Bfl is not oct or hex and _Val == 0xFFFF (-1), then _Val
will be cast to (long)0xFFFFFFFF (-1).

As you can see, the double cast is important if you want to maintain the
literal bit pattern, but the single cast is important if you want to
maintain the logical decimal value.
Mar 30 '08 #6
On Mar 30, 7:06*pm, "Daniel T." <danie...@earthlink.netwrote:
ManicQin <Manic...@gmail.comwrote:
Hi, I've browsed the STL code a bit and stumble upon the next line (in
the operator << overload of both long and short outputs - the line is
for checking does the input is a manipulator)
long _Tmp = (_Bfl == ios_base::oct || _Bfl == ios_base::hex)
* * * * * * * * * * * * * * * * ? (long)(unsigned short)_Val //<-This Line
* * * * * * * * * * * * * * * * *: (long)_Val;
Is there any profound reason why they "Double" casting the _Val?
Thanks.

Let's pretend that _Val is a short and sizeof(short) is 2 and
sizeof(long) is 4...

If _Bfl == oct or hex, and _Val == 0xFFFF (-1), then _Val will be cast
to (unsigned short)0xFFFF (65535) and then to (long)0xFFFF (65535).

whereas if _Bfl is not oct or hex and _Val == 0xFFFF (-1), then _Val
will be cast to (long)0xFFFFFFFF (-1).

As you can see, the double cast is important if you want to maintain the
literal bit pattern, but the single cast is important if you want to
maintain the logical decimal value.
mmm... and that's why the else statement ":" returns just long to
maintain the value...
Ok thanks!
Mar 31 '08 #7
On Mar 31, 8:53 am, ManicQin <Manic...@gmail.comwrote:
On Mar 30, 7:06 pm, "Daniel T." <danie...@earthlink.netwrote:
ManicQin <Manic...@gmail.comwrote:
Hi, I've browsed the STL code a bit and stumble upon the next line (in
the operator << overload of both long and short outputs - the line is
for checking does the input is a manipulator)
long _Tmp = (_Bfl == ios_base::oct || _Bfl == ios_base::hex)
? (long)(unsigned short)_Val //<-This Line
: (long)_Val;
Is there any profound reason why they "Double" casting the _Val?
Thanks.
Let's pretend that _Val is a short and sizeof(short) is 2 and
sizeof(long) is 4...
If _Bfl == oct or hex, and _Val == 0xFFFF (-1), then _Val will becast
to (unsigned short)0xFFFF (65535) and then to (long)0xFFFF (65535).
whereas if _Bfl is not oct or hex and _Val == 0xFFFF (-1), then _Val
will becastto (long)0xFFFFFFFF (-1).
As you can see, the doublecastis important if you want to maintain the
literal bit pattern, but the singlecastis important if you want to
maintain the logical decimal value.

mmm... and that's why the else statement ":" returns just long to
maintain the value...
Ok thanks!
Just wondering, is there an obvious reason why STL doesn't use the C++
cast operators? In this case I believe the appropriate one would be
static_cast<>.

T
Mar 31 '08 #8
On 31 Mar, 22:50, tommy.hi...@gmail.com wrote:
[snip]
Just wondering, is there an obvious reason why STL doesn't use the C++
cast operators? In this case I believe the appropriate one would be
static_cast<>.
I'd just like to point out that the example you refer to is from an
iostreams implementation, which is not part of the STL. It could be
that this code was written before the "new" cast operators became
widely used, or maybe this particular implementor prefers the C-style
cast.

I could be wrong, but I do believe the original STL implementation
predates the new cast operators. However, there are certainly STL
implementations that uses them. (SGI, for example).

DP
Apr 1 '08 #9

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

reply views Thread by Aaron W. West | last post: by
15 posts views Thread by Michael Baehr | last post: by
182 posts views Thread by Jim Hubbard | last post: by
8 posts views Thread by TS | last post: by
14 posts views Thread by grid | last post: by
6 posts views Thread by Jack | last post: by
3 posts views Thread by gieforce | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.