请考虑以下代码:
#include <hal_types.h>
int main() {
uint16 crc16; // hal_types.h: typedef unsigned short uint16;
crc16 = 0x43; // debugger: crc16 == 0x0043, as expected
crc16 = crc16 << 8; // crc16 == 0x0000 ????
return 0;
}
此代码在TI CC1111 SoC(带有8051内核)上运行,并使用IAR EW8051 8.10.3进行编译/调试,配置为使用C99方言,无需优化。使用IAR调试器观察注释中的值(使用模拟器或实际设备的结果相同)。
我希望在crc16 = crc16 << 8;
之后,crc16
的值为0x4300
,而不是0x0000
。
根据C99标准(以及2005年5月5日至2005年5月的草案),第6.5.7.3-4节。
对每个操作数执行整数提升。类型 结果是提升左操作数的结果。如果值 右操作数为负数或大于或等于宽度 在提升的左操作数中,行为未定义。
E1的结果&lt;&lt; E2是E1左移E2位位置;空出的位 充满了零。如果E1具有无符号类型,则为结果的值 是E1×2 ^ E2,减去模数比可表示的最大值 结果类型。如果E1具有带符号类型和非负值,则 E1×2 ^ E2在结果类型中是可表示的,然后就是结果 值;否则,行为未定义。
我对此的看法是结果类型应该是无符号的16位整数,其值为((0x0043)*(2^8)) % 0x10000 == 0x4300
。
我错过了什么吗?感谢。
答案 0 :(得分:1)
我弄明白发生了什么。即使没有优化,我没有使用crc16的事实似乎改变了语义。如果我在最后添加以下行,
if (crc16)
crc16 = 0x1234;
然后crc16在crc16 = crc16&lt;&lt;之后具有期望值(0x4300)。 8;
答案 1 :(得分:1)
您也可以将crc16声明为易失性,正如Adam Casey评论的那样。