在 avr-gcc 编译器上进行位移时是否存在错误?

问题描述

在 avr-gcc 5.4.0 下处理 atmega328 芯片上的位移时,我注意到一个错误(?)。让我们看看一些片段:

代码按预期工作:

uint32_t val = 0xaabbccdd;
Serial.println( val,HEX ); //Output: aabbccdd
// For testing 32 bit variables

这个也有效:

uint16_t read = 0x3FF;
uint32_t val = read * 65536;
Serial.println( val,HEX ); // Output: 3ff0000

但这不是!:

uint16_t read = 0x3FF;
uint32_t val = read << 16;
Serial.println( val,HEX ); // Output: 0

(如果值小于 16,系统甚至会崩溃!)

编译器中是否有任何已知错误

谢谢!

解决方法

   uint16_t read = 0x3FF;
   uint32_t val = read << 16;

由于 read 只有 16 位宽并且从右侧移入了 16 个零,因此 val 中的结果是 0。您必须按照评论中的建议对 uint32_t 进行显式转换。

   uint16_t read = 0x3FF;
   uint32_t val = read * 65536;

无需强制转换即可工作,因为 65536 被作为 int32_t 处理(因为它不适合 uint16_t),因此乘法的结果是 int32_t 并且不会溢出。