在布尔值上使用按位非运算符 (~) 是否会调用未定义的行为?

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