I have the following example, compiled in VS2005, warning level 4:
int main(int argc, char *argv[])
{
short s = 2;
short t = 3;
t *= s; // warning C4244: '*=' : conversion from 'int' to 'short', possible loss of data
t = t * s;
}
It doesn't seem to me there should be a warning on either line.
Does *= create an implicit conversion to int for some reason?
EDIT:
Seems like the lack of warning on the second line (and in VS2008) are the real questions.
Thanks for the answers.
Yes. All arithmetic operators in C++ are defined on int
and wider. When you multiply two short
s (doesn't matter if you use *
or *=
) they are both converted to int
first. This is covered by ISO C++ 5[expr]/9:
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:
- If either operand is of type long double, the other shall be converted to long double.
- Otherwise, if either operand is double, the other shall be converted to double.
- Otherwise, if either operand is float, the other shall be converted to float.
- Otherwise, the integral promotions (4.5) shall be performed on both operands.
- Then, if either operand is unsigned long the other shall be converted to unsigned long.
- Otherwise, if one operand is a long int and the other unsigned int, then if a long int can represent all the values of an unsigned int, the unsigned int shall be converted to a long int; otherwise both operands shall be converted to unsigned long int.
- Otherwise, if either operand is long, the other shall be converted to long.
- Otherwise, if either operand is unsigned, the other shall be converted to unsigned.
[Note: otherwise, the only remaining case is that both operands are int]
and 4.5[conv.prom]:
1 An rvalue of type char, signed char, unsigned char, short int, or unsigned short int can be converted to an rvalue of type int if int can represent all the values of the source type; otherwise, the source rvalue can be converted to an rvalue of type unsigned int.
2 An rvalue of type wchar_t (3.9.1) or an enumeration type (7.2) can be converted to an rvalue of the first of the following types that can represent all the values of its underlying type: int, unsigned int, long, or unsigned long.
3 An rvalue for an integral bit-field (9.6) can be converted to an rvalue of type int if int can represent all the values of the bit-field; otherwise, it can be converted to unsigned int if unsigned int can represent all the values of the bit-field. If the bit-field is larger yet, no integral promotion applies to it. If the bit-field has an enumerated type, it is treated as any other value of that type for promotion purposes.
4 An rvalue of type bool can be converted to an rvalue of type int, with false becoming zero and true becoming one.
5 These conversions are called integral promotions.
Why it only gives a warning on one line but not both is unclear, however.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With