我有以下示例,在VS2005中编译,警告级别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;
}
Run Code Online (Sandbox Code Playgroud)
在我看来,任何一条线都不应该有警告.
由于某种原因,*=是否创建了对int的隐式转换?
编辑:
似乎第二行(以及在VS2008中)缺少警告是真正的问题.
谢谢你的回答.
Pav*_*aev 12
是.C++中的所有算术运算符都定义在int
更宽的范围内.当你乘以2时short
(如果使用*
或者无关紧要*=
)它们都被转换为int
第一个.这由ISO C++ 5 [expr]/9涵盖:
许多期望算术或枚举类型的操作数的二元运算符会以类似的方式引起转换并产生结果类型.目的是产生一个通用类型,它也是结果的类型.此模式称为通常的算术转换,其定义如下:
- 如果任一操作数的类型为long double,则另一个操作数应转换为long double.
- 否则,如果任一操作数为double,则另一个操作数应转换为double.
- 否则,如果任一操作数是浮点数,则另一个操作数应转换为浮点数.
- 否则,应对两个操作数执行整体促销(4.5).
- 然后,如果任一操作数是无符号长的,则另一个操作数应转换为无符号长整数.
- 否则,如果一个操作数是long int而另一个是unsigned int,那么如果long int可以表示unsigned int的所有值,则unsigned int应该转换为long int; 否则两个操作数都应转换为unsigned long int.
- 否则,如果任一操作数为long,则另一个操作数应转换为long.
- 否则,如果任一操作数是无符号的,则另一个操作数应转换为无符号.
[注意:否则,唯一剩下的情况是两个操作数都是int]
和4.5 [conv.prom]:
1如果int可以表示源类型的所有值,则可以将char,signed char,unsigned char,short int或unsigned short int类型的rvalue转换为int类型的rvalue.否则,源rvalue可以转换为unsigned int类型的rvalue.
2类型为wchar_t(3.9.1)或枚举类型(7.2)的rvalue可以转换为以下第一种类型的rvalue,它可以表示其基础类型的所有值:int,unsigned int,long,或者无符号长.
3如果int可以表示位域的所有值,则可以将积分位域(9.6)的rvalue转换为int类型的rvalue; 否则,如果unsigned int可以表示位字段的所有值,则可以将其转换为unsigned int.如果位字段较大,则不适用整数提升.如果位字段具有枚举类型,则将其视为该类型的任何其他值以用于促销目的.
4 bool类型的rvalue可以转换为int类型的rvalue,false变为零,true变为1.
5这些转换称为整体促销.
然而,为什么它只在一行上发出警告但不是两者都不清楚.