我在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
WTF?当它应该是按位AND与0x1的结果时,firstOk怎么能是244?我知道布尔值实际上存储为整数,但是我的按位AND怎么可能被忽略?因为它是244,所以当它应该是假的时候它被评估为真,这是问题的原因。
是不是将按位AND的结果赋给布尔值安全?这是一个gcc bug吗?或者我应该做以下的事情?
bool firstOk = (status & 0x1) ? true : false;
提前致谢。
答案 0 :(得分:2)
当您到达firstOk
来电时,本地变量secondOk
和sleep()
并非“有效”,因此即使他们已经分配了堆叠广告位,它完全有可能(实际上很可能)它们的值不再存储在任何地方。
如果您需要调试其中任何一个变量,则需要
static
,这将从堆栈中分配持久存储firstOk
和secondOk
的声明移至外部范围。 (注意,这可能还不够,除非你将它们移到文件范围。)firstOk
和secondOk
的值复制到外部作用域中的持久变量或变量,并检查它们。在任何情况下,一旦完成调试过程,我将恢复上述任何调试措施。 :-)
关于你的最后一个问题,声明bool firstOk = status & 0x1
完全没问题,正如设置secondOk
之后的声明一样。将int
分配给bool
将零/非零值强制为false
和true
。
至于你的实际错误(不知怎的,你错过了firstOk
上的转换),我看不出你在这段代码中丢失它的位置。这部分代码似乎很好。是否有可能需要更频繁地调用getStatus()
函数而不是每秒一次?其他任何内容都可以写入m_firstOk
或m_secondOk
吗?他们的声明没有显示,所以可能这些声明存在于外部范围内。
答案 1 :(得分:0)
唯一可行的方法是:
1)堆栈已被某种方式覆盖。
2)一旦你进入睡眠线,临时值就不那么重要了,所以编译器不再跟踪它了,所以内存插槽可能已被用于其他东西了!
如果它首先工作然后再开始表现不对,则很可能不是该部分代码的编译器错误。
答案 2 :(得分:-1)
正确的作业应该是:
bool firstOk = (status & 0x1) == 0x01;
或者一般来说:
bool flag = (value & mask) == mask;