在布尔值上使用按位非运算符 (~) 是否会调用未定义的行为?
Does using bitwise not operator (~) on boolean values invoke Undefined Behavior?
如果 C++ 程序将按位非运算符 (~) 应用于布尔值,是否会调用未定义行为?
例如以下程序定义明确吗?
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?
(是的,我知道有一个 ! 运算符更适合这类事情;出于这个问题的目的,我们将忽略它的存在;))
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
,它不是零。促销也可能在起作用,但它是同一个调子。
这里的关键是 "bitwise" 而不是 "logical"。所以人们不应该期望两者匹配,除非布尔表示是一位。
轻松完全定义行为。
算术运算符对其操作数执行整数提升。具体来说 [expr.unary.op]/9 表示 ~
也会发生这种情况。
因此 ~t
与 ~1
相同。这给出了一个有效的非零整数。
整数到布尔的转换由 [conv.bool] 定义:
A zero value, null pointer value, or null member pointer value is converted to false; any other value is converted to true
所以 bool t2 = ~t;
产生 t2 == true
。没有未定义的行为。
~f
等同于 ~0
。在 2 的补码中,~0
给出 -1
,因此我们将有 f2 == true
.
1 的补码——如果曾经有一个 C++ 系统使用 1 的补码——那么 ~0
的效果就不清楚了。
5.3.1/10 The operand of ~
shall have integral or unscoped enumeration type; the result is the one’s complement of its operand. Integral promotions are performed. [emphasis mine]
4.5/6 A prvalue of type bool
can be converted to a prvalue of type int
, with false
becoming zero and true
becoming one.
4.5/7 These conversions are called integral promotions.
所以 ~false
是一个 int
,其位模式由全 1 组成 - 表示 0 的位模式的补码,即全零(根据 3.9 的要求。 1/7.) 类似地,~true
是一个 int
,它是 1 的位表示的补码——即最低有效位为零的所有位。在布尔上下文中,这两个值都将计算为 true
。
如果 C++ 程序将按位非运算符 (~) 应用于布尔值,是否会调用未定义行为?
例如以下程序定义明确吗?
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?
(是的,我知道有一个 ! 运算符更适合这类事情;出于这个问题的目的,我们将忽略它的存在;))
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
,它不是零。促销也可能在起作用,但它是同一个调子。
这里的关键是 "bitwise" 而不是 "logical"。所以人们不应该期望两者匹配,除非布尔表示是一位。
轻松完全定义行为。
算术运算符对其操作数执行整数提升。具体来说 [expr.unary.op]/9 表示 ~
也会发生这种情况。
因此 ~t
与 ~1
相同。这给出了一个有效的非零整数。
整数到布尔的转换由 [conv.bool] 定义:
A zero value, null pointer value, or null member pointer value is converted to false; any other value is converted to true
所以 bool t2 = ~t;
产生 t2 == true
。没有未定义的行为。
~f
等同于 ~0
。在 2 的补码中,~0
给出 -1
,因此我们将有 f2 == true
.
1 的补码——如果曾经有一个 C++ 系统使用 1 的补码——那么 ~0
的效果就不清楚了。
5.3.1/10 The operand of
~
shall have integral or unscoped enumeration type; the result is the one’s complement of its operand. Integral promotions are performed. [emphasis mine]4.5/6 A prvalue of type
bool
can be converted to a prvalue of typeint
, withfalse
becoming zero andtrue
becoming one.4.5/7 These conversions are called integral promotions.
所以 ~false
是一个 int
,其位模式由全 1 组成 - 表示 0 的位模式的补码,即全零(根据 3.9 的要求。 1/7.) 类似地,~true
是一个 int
,它是 1 的位表示的补码——即最低有效位为零的所有位。在布尔上下文中,这两个值都将计算为 true
。