Microsoft C++ compiler have a bug?

断了今生、忘了曾经 提交于 2021-01-29 03:57:18

问题


usigned int x=1;
signed int y = -1;
double z = y * x * 0.25;

I'm using Microsoft Visual Studio 10 C++ compiler. Why z don't have -0.25 value? As I saw from disassembly, it makes an signed int multiply (imul), places the result from edx on the stack, and extends it with 0!, as it would be an unsigned int. After that it multiplies it using FP instructions.

.............
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]

Why the result of multiply of signed * unsigned is interpreted as unsigned?


回答1:


The expression y * x * 0.25 associates as (y * x) * 0.25 in both C and C++.

When multiplying an unsigned int and a signed int, both operands are converted to unsigned int and the results is also an unsigned int due to the integer conversion rules for arithmetic expressions in both C and C++ so the result of y * x will be UINT_MAX - 1 in both C and C++.

Your example doesn't exhibit a compiler bug whether you are compiling your example as C or C++.




回答2:


This is actually according to the spec. C++11, 5.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:

[...]

Otherwise, the integral promotions (4.5) shall be performed on both operands. Then the following rules shall be applied to the promoted operands:

[...]

  • Otherwise, if the operand that has unsigned integer type has rank greater than or equal to the rank of the type of the other operand, the operand with signed integer type shall be converted to the type of the operand with unsigned integer type.

Here the two operands in y * x are signed and unsigned int, which have an equal integer conversion rank; so y ends up being converted to unsigned.




回答3:


This is described in the [expr] section of the standard:

....

Otherwise, the integral promotions (4.5) 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.

— Otherwise, if both operands have signed integer types or both have unsigned integer types, the operand with the type of lesser integer conversion rank shall be converted to the type of the operand with greater rank.

— Otherwise, if the operand that has unsigned integer type has rank greater than or equal to the rank of the type of the other operand, the operand with signed integer type shall be converted to the type of the operand with unsigned integer type.

The expression is evaluated left to right and so y * x is calculated first. This has two integral types of the same rank, one operand signed and the other unsigned. Hence the signed value is converted to an unsigned value, as described in the final paragraph of the standards extract.



来源:https://stackoverflow.com/questions/10751470/microsoft-c-compiler-have-a-bug

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!