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

时间:2015-04-01 23:06:19

标签: c++ bit-manipulation language-lawyer undefined-behavior

如果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?

(是的,我知道有一个!运算符更适合这类事情;出于这个问题的目的,我们将忽略它的存在;)

3 个答案:

答案 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 。)同样,~trueint的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,这不是零。促销也可能在起作用,但它是一样的。

这里的关键是“按位”而非“逻辑”。所以不应该指望两者匹配,除非布尔表示是单个位。

轻松完全定义的行为。