【发布时间】:2016-11-03 08:10:09
【问题描述】:
以下代码已在 3 个不同的编译器和 3 个不同的处理器上编译,并给出了 2 个不同的结果:
typedef unsigned long int u32;
typedef signed long long s64;
int main ()
{ u32 Operand1,Operand2;
s64 Result;
Operand1=95;
Operand2=100;
Result= (s64)(Operand1-Operand2);}
Result 产生 2 个结果:
任何一个
-5 或 4294967291
我知道(Operand1-Operand2) 的操作是作为 32 位无符号计算完成的,然后当转换为 s64 时,符号扩展在第一种情况下正确完成,但在第二种情况下没有正确完成。
我的问题是符号扩展是否可以通过编译器选项进行控制,或者它是依赖于编译器的,或者它是依赖于目标的。
【问题讨论】:
-
您做出了各种不正确的假设,最严重的是
unsigned long是 32 位,这对于大多数现代操作系统来说通常是不正确的。使用<cstdint>和适当的固定宽度类型。 -
" 是作为 32 位无符号计算完成的" 无法保证。仅仅因为您决定将
typedef某事改名为u32,并不意味着这是真的。如果你需要固定宽度的整数,C++11 提供了它们via a header file -
Operand1-Operand2是无符号的,因此当转换为s64时,它总是零扩展。可能有问题的是您没有显示的打印功能 -
你是怎么检查的?而且您仍然没有提供您正在使用哪个编译器/目标以及如何打印它
-
使用固定宽度的类型并重复测试,会让人混淆
unsigned long在各个平台上的大小。
标签: c++ compiler-options