Why do they cast it twice?

M

ManicQin

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::eek:ct || _Bfl == ios_base::hex)
? (long)(unsigned short)_Val //<-This Line
: (long)_Val;

Is there any profound reason why they "Double" casting the _Val?
Thanks.
 
J

James Kanze

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::eek:ct || _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).
 
B

Bo Persson

ManicQin said:
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::eek:ct || _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
 
M

ManicQin

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)
 
B

Bo Persson

ManicQin said:
The same behavior returns when _Val is long and short.


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
 
J

Juha Nieminen

Bo said:
It will not be the same if the short value is negative.

That line looks suspicious to me.

We can probably assume that _Val is a signed type. Let's also assume
that in a particular architecture a short value is 2 bytes.

So what happens if _Val has a value of, for example -10? When it's
cast to unsigned short it will get the value 65526, which is then cast
to a signed long, which gets that (signed) value 65526.

I can't even begin to imagine which application would find useful to
have the signed long value 65526 from the original value -10.
 
D

Daniel T.

ManicQin said:
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::eek:ct || _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.
 
M

ManicQin

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!
 
T

tommy.hinks

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
 
T

Triple-DES

On 31 Mar, 22:50, (e-mail address removed) 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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,756
Messages
2,569,540
Members
45,025
Latest member
KetoRushACVFitness

Latest Threads

Top