~ 运算符为布尔而努力

~ operator acts strangly for bool

本文关键字:努力 布尔 运算符      更新时间:2023-10-16

按位补码运算符对布尔操作数做了意想不到的事情。下面的程序生成此输出:

x: 123456fe   ~x: 87654301   !x: 556677ff
x: 123456ff   ~x: 87654301   !x: 556677fe

对于 X 中的任何字节值,~X 似乎总是用 01 覆盖整个字节。!然而,X 似乎只补充了字节的 LSB......

我想如果将布尔值

转换为 int,应用按位补码,并将结果转换回布尔值,这是有道理的。 但是,我不明白为什么一个结果会将 8 位写入内存,而另一个结果只写入 1 位。

#include "stdio.h"
typedef union {
    bool b;
    unsigned int i;
} ib_T; 
int main(int argc, char **argv) {
    ib_T x, y, z;
    x.i = 0x123456fe;
    y.i = 0x876543ff;
    z.i = 0x55667777;
    y.b = ~x.b;
    z.b = !x.b;
    printf("x: %08x   ~x: %08x   !x: %08xn", x.i, y.i, z.i);
    x.i = 0x123456ff;
    y.b = ~x.b;
    z.b = !x.b;
    printf("x: %08x   ~x: %08x   !x: %08xn", x.i, y.i, z.i);
}

从以前未分配到的联合成员读取是未定义的行为。

在联合中,最多一个非静态数据成员可以随时

处于活动状态,也就是说,最多一个非静态数据成员的值可以随时存储在联合中。

当类型共享通用布局时,此规则有一个例外,这不适用于您的情况。通常,如果分配给x.i,则只能从x.i读取;如果要从x.b开始读取,则需要先分配给x.b

我想如果将布尔值

转换为 int,应用按位补码,并将结果转换回布尔值,这是有道理的。

这是 100% 正确的:下面的代码片段

bool b;
b = false;
printf("b: %dn", b);
b = ~b;
printf("~b: %dn", b);
b = ~b;
printf("~~b: %dn", b);

指纹

b: 0
~b: 1
~~b: 1

bool提升为 int,应用波浪号~,然后使用通常的"零/不零"规则将结果转换回bool