2012-06-28 32 views
2

按位补码运算符对bool操作数做出意想不到的事情。下面的程序产生这样的输出:〜运算符为bool作stra 012作用

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

对于X的任何字节值,〜X似乎总是与01 X,但是,似乎只补充LSB字节的覆盖整个字节..!

我猜这是有道理的,如果bool被转换为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: %08x\n", x.i, y.i, z.i); 

    x.i = 0x123456ff; 
    y.b = ~x.b; 
    z.b = !x.b; 
    printf("x: %08x ~x: %08x !x: %08x\n", x.i, y.i, z.i); 
} 

回答

6

从以前未分配过的工会成员中读取是未定义的行为。

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

这种规则有一个例外,当类型共享一个共同的布局,这不适用于你的情况。一般来说,如果您分配给x.i,那么您只能从x.i中读取;如果您想从x.b开始阅读,则需要先指定x.b

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

这是100%正确的:下面

bool b; 
b = false; 
printf("b: %d\n", b); 
b = ~b; 
printf("~b: %d\n", b); 
b = ~b; 
printf("~~b: %d\n", b); 

打印摘录

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

bool被提升为int,波浪~被施加,然后将结果转换回bool使用通常的“零/不零”规则。

+0

链接到关于未定义的行为和鼻恶魔的解释页会很好 – Vlad

+0

@Vlad维基百科文章链接到C和C++标准文档。 –