asu*_*asu 1 c++ visual-studio-2010 visual-c++
usigned int x=1;
signed int y = -1;
double z = y * x * 0.25;
Run Code Online (Sandbox Code Playgroud)
我正在使用Microsoft Visual Studio 10 C++编译器.为什么z没有-0.25值?正如我从反汇编中看到的那样,它使得一个有符号的int乘法(imul),将edx的结果放在堆栈上,并用0!扩展它,因为它将是一个unsigned int.之后,它使用FP指令将其相乘.
.............
imul edx,dword ptr [ecx]
mov dword ptr [ebp-98h],edx
mov dword ptr [ebp-94h],0
fild dword ptr [ebp-98h]
fmul qword ptr [__real@3fd0000000000000 (1402FB8h)]
fstp qword ptr [z]
Run Code Online (Sandbox Code Playgroud)
为什么signed*unsigned的乘法结果被解释为无符号?
表达式在C和C++中都是y * x * 0.25关联的(y * x) * 0.25.
当乘以a unsigned int和a时signed int,两个操作数都被转换为unsigned int,结果也是unsigned int由于C和C++中算术表达式的整数转换规则,因此结果y * x将UINT_MAX - 1在C和C++中.
无论您是将示例编译为C还是C++,您的示例都不会出现编译器错误.
这实际上是根据规范.C++ 11,5.9:
许多期望算术或枚举类型的操作数的二元运算符会以类似的方式引起转换并产生结果类型.目的是产生一个通用类型,它也是结果的类型.此模式称为通常的算术转换,其定义如下:
[...]
否则,应对两个操作数执行整体促销(4.5).然后,以下规则应适用于提升的操作数:
[...]
- 否则,如果具有无符号整数类型的操作数的秩大于或等于另一个操作数的类型的秩,则具有有符号整数类型的操作数应转换为具有无符号整数类型的操作数的类型.
这里的两个操作数y * x是signed和unsigned int,它们具有相等的整数转换等级 ; 所以y最终被转换为无符号.