我在 C++ 中有以下循环,用 g++ 4.1.2 编译:
while(1) {
int status = getStatus();
bool firstOk = status & 0x1;
bool secondOk = status & 0x2;
if(firstOk != m_firstOk) {
logStatus(1, firstOk);
m_firstOk = firstOk;
}
if(secondOk != m_secondOk) {
logStatus(2, secondOk);
m_secondOk = secondOk;
}
sleep(1);
}
注意 logStatus() 按值接收其参数,因此不会修改该参数。 m_firstOk 和 m_secondOk 当然是 bool 成员属性。
到目前为止,这一切正常。我收到了一个报告,它没有检测到 firstOk 何时更改。我用 gdb 附加到正在运行的进程。它在 sleep() 行中,当我看到以下内容时,我感到惊讶:
(gdb) p m_firstOk
$1 = true
(gdb) p m_secondOk
$2 = true
(gdb) p firstOk
$3 = 244
跆拳道?当 firstOk 应该是 0x1 按位 AND 的结果时,它怎么可能是 244?我知道 boolean 值实际上存储为整数,但是我的按位 AND 怎么会被忽略?由于它是 244,它在它应该是假的时候被评估为真,这就是问题的原因。
不是将按位 AND 的结果分配给 boolean 保险箱吗?这是一个gcc错误吗?或者我应该执行以下操作?
bool firstOk = (status & 0x1) ? true : false;
提前致谢。
最佳答案
当您到达 firstOk
调用时,局部变量 secondOk
和 sleep()
不是“事件的”,因此即使它们已经被分配了堆栈槽,它们的值也完全有可能(实际上很有可能)不再存储在任何地方。
如果您需要调试这些变量中的任何一个,则需要
static
,这将为它们分配堆栈外的持久存储 firstOk
和 secondOk
的声明移动到外部作用域。 (注意,这可能还不够,除非您将它们移出文件范围。) firstOk
和 secondOk
的值复制到持久变量或外部作用域中的变量,并检查它们。 无论如何,一旦您完成调试过程,我将恢复上述任何调试措施。 :-)
至于你的最后一个问题,语句
bool firstOk = status & 0x1
非常好,它后面的语句设置 secondOk
也是如此。将 int
分配给 bool
会将零/非零值强制给 false
和 true
。至于您的实际错误(不知何故,您错过了
firstOk
上的转换),我看不出您在此代码中可能在哪里丢失了它。这部分代码看起来不错。您的 getStatus()
函数是否可能需要比每秒一次更频繁地调用?还有什么可以写入 m_firstOk
或 m_secondOk
吗?它们的声明没有显示,所以大概它们存在于外部作用域中。关于C++:将按位 AND 的结果分配给 bool,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14892779/