2

ビットごとの補数演算子は、bool オペランドに対して予期しないことを行います。以下のプログラムは、この出力を生成します。

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

X の任意のバイト値について、~X は常にバイト全体を 01 で上書きするようです。ただし、!X はバイトの LSB のみを補完するようです...

boolがintに変換され、ビットごとの補数が適用され、結果がboolに変換される場合、これは理にかなっていると思います。 しかし、なぜ1つの結果がメモリに8ビットを書き込み、もう1つの結果が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);
}
4

1 に答える 1

7

以前に割り当てていない共用体のメンバーからの読み取りは、未定義の動作です。

共用体では、非静的データ メンバーの最大 1 つを常にアクティブにすることができます。つまり、非静的データ メンバーの最大 1 つの値を任意の時点で共用体に格納できます。

タイプが共通のレイアウトを共有する場合、このルールには例外がありますが、これはあなたの場合には当てはまりません。一般に、に割り当てた場合、x.iからのみ読み取ることができますx.i。から読み始めたい場合は、最初x.bに を割り当てる必要がありますx.b

boolがintに変換され、ビットごとの補数が適用され、結果がboolに変換される場合、これは理にかなっていると思います。

これは 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通常の「ゼロ/ゼロではない」ルールを使用して変換されます。

于 2012-06-28T13:22:57.483 に答える