【问题标题】:c++ bool anomaly -- why is this possible?c++ bool 异常——为什么会这样?
【发布时间】:2013-06-24 16:48:31
【问题描述】:

我刚刚偶然发现:当 postifix 将布尔值递增两次时,整数值仍然是 1 而不是预期的 2。我想知道为什么会发生这种情况。

bool test = false; // results in integer 0
test++; // results in integer 1
test++; // results in integer 1

// but there still is at least one byte of memory used:
// results in integer 137
*(unsigned char*)(&test) = 137;

【问题讨论】:

  • 在不查看由此产生的任何机器代码的情况下,我会假设当您告诉编译器在 @987654322 上工作时,编译器会忽略除最不重要的 bit 之外的所有内容@。 bool + 1 也有可能变成 bool & 1 作为优化或防止溢出,这会导致您看到的行为。编译器可能会做一些更聪明的事情;你真的应该包含这段代码的程序集。
  • A bool 只能是 truefalse,将其设置为 137 是未定义的行为

标签: c++ language-features


【解决方案1】:

这就是++ 运算符的指定方式。参见 C++11 §5.2.6[expr.post.incr]/1(强调我的):

后缀++ 表达式的值是其操作数的值。 [注:得到的值是原始值的副本——尾注] 操作数应为可修改的左值。操作数的类型应为算术类型或指向完整对象类型的指针。

操作数对象的值通过加 1 来修改,除非对象是 bool 类型,在这种情况下它被设置为 true。 [注意:不推荐使用此用法,请参阅附录 D.——尾注]

(前缀++ 运算符具有相似的语言,可以将其应用于bool 值。)

通过非bool 类型的指针或引用修改bool 对象会产生未定义的行为。

【讨论】:

  • 我猜想将-- 应用于bool 会将其设置为false,那么,不管其先前的状态如何?
  • @JAB: 不可以。前缀和后缀 -- 都不能应用于 bool 类型的操作数。
  • 通过unsigned char 别名是允许的。 UB 不仅仅来自于修改它,它来自于写入一个不在bool 的值表示中的值。这很好:例如bool d, s = true; std::memcpy(&d, &s, sizeof(bool)); /* loop char by char */
【解决方案2】:

为什么会这样?!

未定义的行为就是这样 - 未定义。任何事情都有可能发生。

如果为137 分配了足够的内存,那该死的test++;结果1?

语言规范定义了该行为。

【讨论】:

    【解决方案3】:

    因为您通过将指针转换为不同的类型并对其执行读/写来调用未定义的行为。 UB = 任何事情都有可能发生,包括鼻恶魔。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-24
      • 1970-01-01
      • 1970-01-01
      • 2018-10-15
      相关资源
      最近更新 更多