Reputation: 326
I have the following code:
int main()
{
short s(0);
long l(10);
s += static_cast<short>(l);
}
I'm compiling this with g++ and I get the following error:
..\src\main.cpp:6:7: warning: conversion to 'short int' from 'int' may alter its value [-Wconversion]
I absolutely have no idea why this is happening, as I thought that "static_cast" permitted to avoid this king of warnings.
Thanks for any help provided.
Upvotes: 2
Views: 3005
Reputation: 41220
Integral promotion of short
is required, so widening is unavoidable, however if you perform a static_cast
you'll cast the result back to a short
In a nutshell:
short
= short
+ short
static_cast
of the long
made the second value a short
)short
= int
+ int
int
to short
creates a warningFrom [expr]:
Many binary operators that expect operands of arithmetic or enumeration type cause conversions and yield result types in a similar way. The purpose is to yield a common type, which is also the type of the result. This pattern is called the usual arithmetic conversions, which are defined as follows:
...
Otherwise, the integral promotions (7.6) shall be performed on both operands. Then the following rules shall be applied to the promoted operands
- If both operands have the same type, no further conversion is needed.
From [conv.prom]
A prvalue of an integer type other than
bool
,char16_t
,char32_t
, orwchar_t
whose integer conversion rank (7.15) is less than the rank of int can be converted to a prvalue of typeint
ifint
can represent all the values of the source type; otherwise, the source prvalue can be converted to a prvalue of typeunsigned int
.
And indeed short
has a lower rank than int
:
From [conv.rank]
The rank of a signed integer type shall be greater than the rank of any signed integer type with a smaller size.
For performing the cast (to make the warning go away), see Richard Crittenden's comments on the OP or Nathan Oliver's answer
Upvotes: 3
Reputation: 181068
Even though you are casting l
to a short
you still have another conversion that is getting in the way. When you do
s += static_cast<short>(l);
[expr.ass]/7 says it is the same as
s = s + static_cast<short>(l)
And this transformation is what is giving you the int
in the warning you receive.
The reason for this is the built in operators don't exist for types smaller than int
. Since both types are short
they are converted to int
which gives you an int
for the result and now you are trying to assign that int
to a short
which could overflow. To workaround this you can use
s = static_cast<short>(s + l);
which converts the result to a short
and then does the assignment.
Upvotes: 2