sci*_*lot 2 c++ bit-shift bitwise-operators
我一直在调试 C++ 库中的一个问题,发现文字 0和设置为 0但仅在库内部的变量之间存在奇怪的差异。如果我将代码复制到我自己的代码中,它会按预期工作。
库代码正在1向下移动一个长整数以一次屏蔽一位。发送某个代码(REPEAT 键)时,您会发送一种虚拟数据包,并且“没有位”,因此它传输标头而不传输数据。我假设如果没有要发送的位,for 循环将跳过循环。
我已经简化了它以分解分配,并添加了以下调试。我只是重复这两个步骤nbits和0我添加的文字。
void IRsend::sendNEC (unsigned long data, int nbits){
Serial.println(data, HEX);
Serial.print(" nbits = ");
Serial.println( nbits);
if(nbits == 0) Serial.println("nbits == 0"); else Serial.println("nbits != 0 ");
Serial.print(" 0 - 1 = ");
Serial.println(0 - 1);
Serial.print(" nbits - 1 = ");
Serial.println(nbits - 1);
Serial.print(" (1UL << (0 - 1) = ");
Serial.println(1UL << (0 - 1));
Serial.print(" (1UL << (nbits - 1) = ");
Serial.println(1UL << (nbits - 1));
...
// the part I was originally debugging:
for (unsigned long mask = 1UL << (nbits - 1); mask; mask >>= 1) {
...
}
called like:
irsend.sendNEC(0xFFFFFFFF, 0);
Run Code Online (Sandbox Code Playgroud)
这令人惊讶地给出了以下输出:
FFFFFFFF
nbits = 0
nbits == 0
0 - 1 = -1
nbits - 1 = -1
(1UL << (0 - 1) = 0
(1UL << (nbits - 1) = 1
Run Code Online (Sandbox Code Playgroud)
最后两个结果怎么可能不同?nbit是 0,那么为什么文字 0 在最终都为 -1 时会发生不同的变化(我添加了额外的括号以确保)?
为什么,当我将完全相同的调试代码复制到调用该库的代码中,并调用如下测试函数时:
void runtest(unsigned long data, int nbits){
/// same debug ...
}
void setup() {
runtest(0xFFFFFFFF, 0);
}
Run Code Online (Sandbox Code Playgroud)
我得到预期的输出:
-- Same test again --
FFFFFFFF
nbits = 0
nbits == 0
0 - 1 = -1
nbits - 1 = -1
(1UL << (0 - 1) = 0
(1UL << (nbits - 1) = 0
Run Code Online (Sandbox Code Playgroud)
我只能准确地猜测 0 == 0,例如,如果它默认为更长的类型 0?
这是使用 Arduino IRRemote 库:https : //github.com/z3t0/Arduino-IRremote/blob/master/ir_NEC.cpp
它在 ATmega328 上运行,我在 MacOSX 上构建,大概是在 Arduino 1.8.10 IDE 中使用 avr-gcc。
从 C++ 标准草案expr.shift:
操作数应为整数或无作用域枚举类型,并执行整数提升。结果的类型是提升的左操作数的类型。如果右操作数为负数,或者大于或等于提升的左操作数的宽度,则行为未定义。
您的代码具有未定义的行为,因此任何事情都可能发生。
| 归档时间: |
|
| 查看次数: |
139 次 |
| 最近记录: |