bool布尔变量取反的一个陷阱

发布时间 2023-09-24 21:53:07作者: 百里骑

最近工作上被一个小问题耽误了一些时间,在此记录一下。

问题出在对一个布尔变量的取反上。

我的本意是想检查一个结构体中某 1 bit 是0还是1,我直接进行取反“~”操作,运行是结果跟预想的不一致。才发现这个取反操作是一个坑。

且看下面测试程序:

#define uint32_t unsigned int   

typedef union 
{
    struct {
        uint32_t name       : 8;
        uint32_t age        : 8;
        uint32_t b0         : 1;
        uint32_t b1         : 1;
        uint32_t reserved   : 14;
    } bits;

    uint32_t all;
}ST0;


int main()
{
    printf("=====Test Start.=====\n\n");
    
    bool res0 = 0;
    bool res1 = 0;
    bool res2 = 0;
    uint32_t res0_32 = 0;
    uint32_t res1_32 = 0;

    
    ST0 s0;
    s0.all = 0;
    s0.bits.name = 0xff;

    s0.bits.b0 = 1;
    s0.bits.b1 = 0;

    res0 = ~s0.bits.b0;
    res0_32 = ~s0.bits.b0;
    res1 = ~s0.bits.b1;
    res1_32 = ~s0.bits.b1;

    res2 = !s0.bits.b0;

    printf("The result of bit inverse: res0 =  %d, res1 = %d \n\n", res0, res1);
    printf("The result of bit inverse: res0_32 =  0x%08x, res1_32 = 0x%08x \n\n", res0_32, res1_32);
    printf("The result of bit inverse: res2 =  %d\n\n", res2);

    printf("=====Test End.=====\n\n\n");

    return 0;
}

运行结果如下:

=====Test Start.=====

The result of bit inverse: res0 =  1, res1 = 1 

The result of bit inverse: res0_32 =  0xfffffffe, res1_32 = 0xffffffff 

The result of bit inverse: res2 =  0

=====Test End.=====

最明显的意外之处是,开始s0.bits.b0和s0.bits.b1这两个bit一个是1,一个是0;对它们取反“~”之后赋给一个bool变量,发现结果都是1.

然后我把bool变量的类型改成了32位的无符号数,观察结果发现,实际上程序是s0.bits.b0当作一个32bit的数进行处理的,而不是单纯1bit。

所以前面的结果也就合理了,两个都不是0(res0_32 = 0xfffffffe, res1_32 = 0xffffffff)的数赋值给bool变量,当然结果都是1.

结论是,这种情况下要用“!”而不是“~”。