2012-06-28 33 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++標準文檔。 –