avr-gcc编译器进行位移位时是否有bug?

问题描述 投票:0回答:2

在 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,系统甚至会崩溃!)

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

avr-gcc
2个回答
3
投票
   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 并且不会溢出。


0
投票

是的,有一个错误。我发现这个页面在互联网上搜索“gcc bit shift bug”。

我的 AVR-GCC 代码中有以下几行:

uint32_t startBit
///
startBit = (uint32_t)1 << (combinationLength-1);
///
uint32_t pm
///
pm = (uint32_t)1<<in;
///
uint32_t totalCombinations = (uint32_t)1 << totalInputs;

由于代码的不稳定行为,我每次都必须显式添加强制转换。 第一个是用“1”填充高位,与零相比给出假阴性。 我没有分析第二种情况,第三种情况是通过将 1 移位到位 16 而不是 65536 来生成零,并且似乎在 AVR-GCC 中立即值默认为 16 位,或者位移位默认为 16 -位。

© www.soinside.com 2019 - 2024. All rights reserved.