为什么bool值在C ++中按位而不是按其含义进行比较?

时间:2022-02-25 21:22:09

I would expect the following code to produce equality, but bool values are shown to be different.

我希望以下代码产生相等,但bool值显示不同。

#include <iostream>

union crazyBool
{
    unsigned char uc;
    bool b;
};

int main()
{
    crazyBool a, b;
    a.uc = 1;
    b.uc = 5;

    if(a.b == b.b)
    {
            std::cout << "==" << std::endl;
    }
    else
    {
            std::cout << "!=" << std::endl;
    }

    bool x, y;
    void *xVP = &x, *yVP = &y;
    unsigned char *xP = static_cast<unsigned char*>(xVP);
    unsigned char *yP = static_cast<unsigned char*>(yVP);

    (*xP) = (unsigned char)1;
    (*yP) = (unsigned char)5;

    if(x == y)
    {
            std::cout << "==" << std::endl;
    }
    else
    {
            std::cout << "!=" << std::endl;
    }
    return 0;
}

Note that here we are not only changing the value through union (which was pointed out as being undefined), but also accessing memory directly via void pointer.

请注意,这里我们不仅通过union更改值(指出它是未定义的),而且还通过void指针直接访问内存。

1 个解决方案

#1


If you assign to a member of a union, that member becomes the active member.

如果您指定了union的成员,该成员将成为活动成员。

Reading any member other than the active one is undefined behavior, meaning that anything could happen. There are a few specific exceptions to this rule, depending on the version of the C++ standard your compiler is following; but none of these exceptions apply in your case.

读取除活动成员之外的任何成员是未定义的行为,这意味着任何事情都可能发生。此规则有一些特定的例外情况,具体取决于编译器遵循的C ++标准版本;但这些例外都不适用于您的情况。

(One of the exceptions is that if the union has multiple members of class type where the classes have the same initial members, these shared members can be read through any of the union's members.)

(其中一个例外是,如果联盟有多个类类型的成员,其中类具有相同的初始成员,则可以通过任何联合成员读取这些共享成员。)

Edit to address the question clarification:

编辑以解决问题澄清:

The standard defines bool as having the values true and false, no others. (C++11, 3.9.1/6) It never defines what it means to copy some other bit pattern over the storage (which is what you are doing). Since it doesn't define it, the behavior is undefined too.

该标准将bool定义为具有值true和false,而不是其他值。 (C ++ 11,3.9.1 / 6)它从未定义在存储上复制其他位模式的含义(这就是你正在做的事情)。由于它没有定义它,行为也是未定义的。

Yes, when converting an integer to a bool 0 becomes false and anything else becomes true, but that is just a conversion rule, not a statement about bool's representation.

是的,当将整数转换为bool时,0变为false,其他任何内容都变为true,但这只是一个转换规则,而不是关于bool表示的声明。

#1


If you assign to a member of a union, that member becomes the active member.

如果您指定了union的成员,该成员将成为活动成员。

Reading any member other than the active one is undefined behavior, meaning that anything could happen. There are a few specific exceptions to this rule, depending on the version of the C++ standard your compiler is following; but none of these exceptions apply in your case.

读取除活动成员之外的任何成员是未定义的行为,这意味着任何事情都可能发生。此规则有一些特定的例外情况,具体取决于编译器遵循的C ++标准版本;但这些例外都不适用于您的情况。

(One of the exceptions is that if the union has multiple members of class type where the classes have the same initial members, these shared members can be read through any of the union's members.)

(其中一个例外是,如果联盟有多个类类型的成员,其中类具有相同的初始成员,则可以通过任何联合成员读取这些共享成员。)

Edit to address the question clarification:

编辑以解决问题澄清:

The standard defines bool as having the values true and false, no others. (C++11, 3.9.1/6) It never defines what it means to copy some other bit pattern over the storage (which is what you are doing). Since it doesn't define it, the behavior is undefined too.

该标准将bool定义为具有值true和false,而不是其他值。 (C ++ 11,3.9.1 / 6)它从未定义在存储上复制其他位模式的含义(这就是你正在做的事情)。由于它没有定义它,行为也是未定义的。

Yes, when converting an integer to a bool 0 becomes false and anything else becomes true, but that is just a conversion rule, not a statement about bool's representation.

是的,当将整数转换为bool时,0变为false,其他任何内容都变为true,但这只是一个转换规则,而不是关于bool表示的声明。