让uint8和uint16为8位和16位正整数的数据类型。
uint8 a = 1;
uint16 b = a << 8;
我在32Bit架构上对该程序进行了测试,结果是
b = 256
在具有8位长度的寄存器的系统上使用相同的程序会产生结果:
b = 0吗?
因为寄存器中的所有位都被<< << 8移位为0?
答案 0 :(得分:3)
注册无关。这与您的类型的宽度有关。
当您将值移位比其拥有的位数更多时,该行为是不确定的。编译器,程序,计算机,税务局可以相应地合法证明任何结果。而且,不,that's not just theoretical。
但是,operands in C are promoted before interesting things are done on them。因此,您的uint8_t
在左移之前就变成了int
。
现在发生什么情况取决于您的体系结构(由编译器配置决定):实现中的int
仅8位吗? No, it's not! 然后,结果(无论“寄存器大小”如何)都必须遵守语言规则,并得出数学上适当的答案(256)。而且,即使是这样,您会碰到这种未定义的行为,所以问题就没有意义了。
在引擎盖下,如果需要一个以上的寄存器来保存一个变量,那么这将是并且必须发生的(无论隐含的性能成本如何)。那就是如果根本不使用寄存器。请记住,您是在抽象中编程,而不是手工制作机器代码。您显示的程序片段可以在编译过程中完全优化,完全不需要任何运行时指令。 。
答案 1 :(得分:2)
在具有8位长的寄存器的系统上,同一程序的结果是否为
b=0
?
否。
在表达式a << 8
中,变量a
将在移位之前被提升到int
。并且保证int
至少为16位。
b
在所有平台上的值为256,除非编译器中有错误。
但是,如果将第二行更改为uint32 b = a << 16;
,则可能会得到奇怪的结果。 a
仍将升级为int
,但是如果int
为两个字节长,则a << 16
将调用未定义的行为。