在这种情况下,为什么bool而不是bool都返回true?

fly*_*lyx 69 c++ boolean

这是我的代码:

#include <cstring>
#include <iostream>
int main() {
    bool a;
    memset(&a, 0x03, sizeof(bool));
    if (a) {
        std::cout << "a is true!" << std::endl;
    }
    if (!a) {
        std::cout << "!a is true!" << std::endl;
    }
}
Run Code Online (Sandbox Code Playgroud)

它输出:

a is true!
!a is true!
Run Code Online (Sandbox Code Playgroud)

似乎!运算符bool仅反转最后一位,但每个不相等的值0都被视为true.这导致显示的行为,这在逻辑上是错误的.这是实施中的错误,还是规范允许这样做?请注意,memset可以省略,并且行为可能是相同的,因为a包含内存垃圾.

我正在使用gcc 4.4.5,其他编译器可能会采用不同的方式.

Dav*_*nan 92

标准(3.9.1/6基本类型)说:

bool类型的值为true或false.

....

以本国际标准描述的方式将bool值用作"未定义",例如通过检查未初始化的自动对象的值,可能会使其表现为既不是真也不是假.

您的程序的使用memset导致未定义的行为.其后果可能是价值既不真实也不虚假.

  • 我会添加3.9.1/1"对于无符号字符类型,值表示的所有可能位模式都代表数字.这些要求不适用于其他类型." (14认同)

Mik*_*our 41

这不是"逻辑错误",它是未定义的行为.bool只应该包含两个值中的一个,true或者false.为其分配值将导致转换为其中一个值.通过在其内存上写入任意字节值来打破类型安全(或者,正如您所提到的那样,将其保留为未初始化)不会,因此您最终可能会得到一个既不是true也不是false.

  • @Ben是什么NULL或什么都没有?价值?都不是.在OP的示例中,值为3,您可以看到它既不是真也不是假.这是3. (3认同)
  • @MattMcNabb 这将取决于实现。布尔值在转换为 int 时保证为“0”或“1”。但是,内部表示可能不同。就我们所知,bools 可以存储为 32 位浮点数,然后 `true` 的表示将是 `00 00 80 3F`。 (2认同)
  • @EvgeniSergeev:我不知道你在谈论什么.`bool`有两个值,都不是`0x03`; 使用`memset`将`bool`重新解释为一个或多个字节,并用非`bool`值覆盖它,给出未定义的行为.当然不是"零意味着虚假而其他任何意味着真实"的情况; 只有"真"才意味着真实.你所谈论的"惯例"是一种缺乏布尔类型的C古代方言的解决方法; 不是为了C++. (2认同)