这是我的代码:
#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;
}
}
输出:
a is true!
!a is true!
!
上的bool
运算符似乎只反转最后一位,但每个不等于0
的值都被视为true
。这导致显示的行为,这在逻辑上是错误的。这是实施中的错误,还是规范允许这样做?请注意,memset
可以省略,行为可能是相同的,因为a
包含内存垃圾。
我在gcc 4.4.5上,其他编译器可能采用不同的方式。
答案 0 :(得分:92)
标准(3.9.1 / 6基本类型)说:
bool类型的值为true或false。
...
以本国际标准描述的方式将bool值用作“未定义”,例如通过检查a的值 未初始化的自动对象,可能会使其表现为既不是真也不是假。
您的程序使用memset
会导致未定义的行为。其后果可能是价值既不真实也不虚假。
答案 1 :(得分:41)
它不是&#34;逻辑错误&#34;,它是未定义的行为。 bool
只应包含两个值true
或false
中的一个。为其分配值将导致转换为其中一个值。通过在其内存上写入任意字节值来打破类型安全(或者,正如您所提到的那样,将其保留为未实体化)不会,因此您可能最终得到的值不是true
也不是false
{{1}}。
答案 2 :(得分:3)
在内部,它可能使用按位非(~
运算符)来反转它,当bool为零或全部为时,这将起作用:
a = 00000000 (false)
!a = 11111111 (true)
但是如果你把它设置为三个:
a = 00000011 (true)
!a = 11111100 (also true)