C ++:将按位AND的结果分配给bool

时间:2013-02-15 10:33:07

标签: c++ boolean bitwise-and

我在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;

提前致谢。

3 个答案:

答案 0 :(得分:2)

当您到达firstOk来电时,本地变量secondOksleep()并非“有效”,因此即使他们已经分配了堆叠广告位,它完全有可能(实际上很可能)它们的值不再存储在任何地方。

如果您需要调试其中任何一个变量,则需要

  1. 将它们重新声明为static,这将从堆栈中分配持久存储
  2. firstOksecondOk的声明移至外部范围。 (注意,这可能还不够,除非你将它们移到文件范围。)
  3. firstOksecondOk的值复制到外部作用域中的持久变量或变量,并检查它们。
  4. 在任何情况下,一旦完成调试过程,我将恢复上述任何调试措施。 :-)

    关于你的最后一个问题,声明bool firstOk = status & 0x1完全没问题,正如设置secondOk之后的声明一样。将int分配给bool将零/非零值强制为falsetrue

    至于你的实际错误(不知怎的,你错过了firstOk上的转换),我看不出你在这段代码中丢失它的位置。这部分代码似乎很好。是否有可能需要更频繁地调用getStatus()函数而不是每秒一次?其他任何内容都可以写入m_firstOkm_secondOk吗?他们的声明没有显示,所以可能这些声明存在于外部范围内。

答案 1 :(得分:0)

唯一可行的方法是:

1)堆栈已被某种方式覆盖。

2)一旦你进入睡眠线,临时值就不那么重要了,所以编译器不再跟踪它了,所以内存插槽可能已被用于其他东西了!

如果它首先工作然后再开始表现不对,则很可能不是该部分代码的编译器错误。

答案 2 :(得分:-1)

正确的作业应该是:

bool firstOk = (status & 0x1) == 0x01;

或者一般来说:

bool flag = (value & mask) == mask;