【问题标题】:Does using bitwise not operator (~) on boolean values invoke Undefined Behavior?对布尔值使用按位非运算符 (~) 会调用未定义行为吗?
【发布时间】:2015-04-01 23:06:18
【问题描述】:

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

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

【问题讨论】:

  • 我猜~ 在做任何事情之前将参数提升为int,所以~0 将转换为true。不看就不能百分百确定。
  • @chris,你是对的。
  • 是 UB 做bool b = 13; [或类似的事情]?
  • @MatsPetersson:不,int13 隐式转换为 bool,产生 true

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


【解决方案1】:

5.3.1/10 ~ 的操作数应为整数或无范围枚举类型;结果是其操作数的反码。 进行了整体促销。 [强调我的]

4.5/6bool 类型的纯右值可以转换为int 类型的纯右值,false 变为 0,true 变为 1。

4.5/7这些转化称为整体促销

所以~false 是一个int,其位模式由全1 组成 - 表示0 的位模式的补码,即全零(根据3.9.1/7 的要求。 ) 同样,~true 是一个 int,它是 1 的位表示的反码 - 即所有最低有效位为零的位。这两个值都将在布尔上下文中计算为 true

【讨论】:

  • @MattMcNabb 这个标准在哪里说的?我实际上是在寻找那个措辞,但遗憾的是失败了。 C99 6.2.6.2 中有这样的措辞——也许可以说这个措辞通过引用被纳入 C++ 标准,但这听起来像是一个非常弱的论点。我错过了什么明显的东西吗?
  • @MattMcNabb 啊,对。 “纯二进制计数系统”是我忘记的艺术术语。让我更新答案。
  • 我想有一点空间可以争论负零可能是 0 的替代表示,在一个补码中
  • @MattMcNabb C99 至少限制了如何产生负零(基本上,仅通过位旋转)。只写0(int)false 不应该这样做。但是是的,C++ 标准没有任何类似的措辞。
【解决方案2】:

算术运算符对其操作数执行整数提升。特别是 [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 的效果就不清楚了。

【讨论】:

    【解决方案3】:
    bool t = true;
    bool t2 = ~t;    // is t2 guaranteed to be false, or is this UB?
    

    我想这是不能保证的,看看如何

      bool b = true;
      bool b1 = ~b;
      cout << b1;
    

    输出一个“真”

    我想它与布尔表示有关......如果它是一个字节,那么00000001 将否定11111110 这不是零。促销也可能在发挥作用,但它的调子是一样的。

    这里的关键是它是“按位”而不是“逻辑”。因此,除非布尔表示是单个位,否则不应期望两者匹配。

    易于完全定义的行为。

    【讨论】:

      猜你喜欢
      • 2010-09-06
      • 2010-11-20
      • 1970-01-01
      • 2010-12-16
      • 1970-01-01
      • 1970-01-01
      • 2014-02-20
      • 2018-09-26
      相关资源
      最近更新 更多