如果C ++程序将bitwise-not运算符(〜)应用于布尔值,那么它是否会调用未定义的行为?
E.g。以下程序定义明确吗?
bool f = false;
bool f2 = ~f; // is f2 guaranteed to be true, or is this UB?
bool t = true;
bool t2 = ~t; // is t2 guaranteed to be false, or is this UB?
(是的,我知道有一个!运算符更适合这类事情;出于这个问题的目的,我们将忽略它的存在;)
答案 0 :(得分:8)
5.3.1 / 10
~
的操作数应具有整数或无范围的枚举类型;结果是其操作数的一个补码。 执行整体促销。 [强调我的]4.5 / 6
bool
类型的prvalue可以转换为int
类型的prvalue,其中false
变为零true
成为一个。4.5 / 7 这些转化称为整体促销。
所以~false
是一个int
,其位模式由所有1组成 - 代表0的位模式的一个补码,即全零(根据 3.9的要求)。 1/7 。)同样,~true
是int
的1位补码,也就是所有具有最低有效位的补码零。这两个值都将在布尔上下文中计算为true
。
答案 1 :(得分:3)
算术运算符对其操作数执行整数提升。具体来说,[expr.unary.op] / 9表示这也适用于~
。
因此~t
与~1
相同。这给出了一个有效的非零整数。
整数到布尔的转换由[conv.bool]定义:
将零值,空指针值或空成员指针值转换为false;任何其他值都转换为true
所以bool t2 = ~t;
会产生t2 == true
。没有未定义的行为。
~f
与~0
相同。在2的补码中,~0
给出-1
,因此我们将f2 == true
。
在1的补码中 - 如果有一个C ++系统使用1的补码 - 那么~0
的效果就不清楚了。
答案 2 :(得分:1)
bool t = true;
bool t2 = ~t; // is t2 guaranteed to be false, or is this UB?
我认为无法保证,看看如何
bool b = true;
bool b1 = ~b;
cout << b1;
输出“true”
我想它与布尔表示有关...如果它是一个字节,那么00000001
将否定为11111110
,这不是零。促销也可能在起作用,但它是一样的。
这里的关键是“按位”而非“逻辑”。所以不应该指望两者匹配,除非布尔表示是单个位。
轻松完全定义的行为。