Reputation: 34593
Code:
typedef signed short SIGNED_SHORT; //16 bit
typedef signed int SIGNED_INT; //32 bit
SIGNED_SHORT x;
x = (SIGNED_SHORT)(SIGNED_INT) 45512; //or any value over 32,767
Here is what I know:
Signed 16 bits:
Signed: From −32,768 to 32,767
Unsigned: From 0 to 65,535
Don't expect 45512 to fit into x
as x
is declared a 16 bit signed integer.
How and what does the double casting above do?
Thank You!
Upvotes: 2
Views: 2499
Reputation: 263547
typedef signed short SIGNED_SHORT; //16 bit
typedef signed int SIGNED_INT; //32 bit
These typedef
s are not particularly useful. A typedef does nothing more than provide a new name for an existing type. Type signed short
already has a perfectly good name: "signed short
"; calling it SIGNED_SHORT
as well doesn't buy you anything. (It would make sense if it abstracted away some information about the type, or if the type were likely to change -- but using the name SIGNED_SHORT
for a type other than signed short
would be extremely confusing.)
Note also that short
and int
are both guaranteed to be at least 16 bits wide, and int
is at least as wide as short
, but different sizes are possible. For example, a compiler could make both short
and int
16 bits -- or 64 bits for that matter. But I'll assume the sizes for your compiler are as you state.
In addition, signed short
and short
are names for the same type, as are signed int
and int
.
SIGNED_SHORT x;
x = (SIGNED_SHORT)(SIGNED_INT) 45512; //or any value over 32,767
A cast specifies a conversion to a specified type. Two casts specify two such conversions. The value 45512
is converted to signed int
, and then to signed short
.
The constant 45512
is already of type int
(another name for signed int
), so the innermost cast is fairly pointless. (Note that if int
is only 16 bits, then 45512
will be of type long
.)
When you assign a value of one numeric type to an object of another numeric type, the value is implicitly converted to the object's type, so the outermost cast is also redundant.
So the above code snippet is exactly equivalent to:
short x = 45512;
Given the ranges of int
and short
on your system, the mathematical value 45512
cannot be represented in type short
. The language rules state that the result of such a conversion is implementation-defined, which means that it's up to each implementation to determine what the result is, and it must document that choice, but different implementations can do it differently. (Actually that's not quite the whole story; the 1999 ISO C standard added permission for such a conversion to raise an implementation-defined signal. I don't know of any compiler that does this.)
The most common semantics for this kind of conversion is that the result gets the low-order bits of the source value. This will probably result in the value -20024
being assigned to x
. But you shouldn't depend on that if you want your program to be maximally portable.
Upvotes: 5
Reputation: 28188
The double casting is equivalent to:
short x = static_cast<short>(static_cast<int>(45512));
which is equivalent to:
short x = 45512;
which will likely wrap around so x
equals -20024
, but technically it's implementation defined behavior if a short has a maximum value less than 45512 on your platform. The literal 45512
is of type int
.
Upvotes: 4
Reputation: 213638
When you cast twice, the casts are applied in sequence.
int a = 45512;
int b = (int) a;
short x = (short) b;
Since 45512 does not fit in a short
on most (but not all!) platforms, the cast overflows on those platforms. This will either raise an implementation-defined signal or result in an implementation-defined value.
In practice, many platforms define the result as the truncated value, which is -20024
in this case. However, there are platforms which raise a signal, which will probably terminate your program if uncaught.
Citation: n1525 §6.3.1.3
Otherwise, the new type is signed and the value cannot be represented in it; either the result is implementation-defined or an implementation-defined signal is raised.
Upvotes: 5
Reputation: 10096
You can assume it does two type conversions (although signed int
and int
are only separated once in the C standard, IIRC).
If SIGNED_SHORT is too small to handle 45512, the result is either implementation-defined or an implementation-defined signal is raised. (In C++ only the former applies.)
Upvotes: 2