【问题标题】:CppCheck warning: expression depends on order of evaluation in x = x |= (1 << 3)CppCheck 警告:表达式取决于 x = x |= (1 << 3) 中的评估顺序
【发布时间】:2016-05-26 14:25:02
【问题描述】:

C 中的代码行是

x = x |= (1 << 3);

给出 cppCheck 错误:“表达式 'x=x|=1' 取决于副作用的评估顺序”

而线

x |= (1 << 3);

没问题。

我想

x = x |= (1 << 3);

应该是一样的

x = x = x | (1 << 3);

这只是

x = (x = (x | (1 << 3)));

实际上对 x 的外部赋值没有效果,这意味着结果与

x |= (1 << 3);

那么 CppCheck 到底在抱怨什么?

编辑:认为它与j = j++ 与上述问题中讨论的j++ 相同或不同的原因重复。

【问题讨论】:

标签: c evaluation side-effects cppcheck


【解决方案1】:

@Cornstalks'link on sequence points 的这句话很好地解释了这一点。

表达式...修改相同的值两次是不需要被允许的可憎的(或者在任何情况下,不需要明确定义,即我们不必想办法说它们是什么做,编译器不必支持它们)。

C 标准对这些类型的表达式没有任何要求,因此在所有环境中都不能保证特定的求值顺序。

一个相当快速&&简单的解释:

x = x |= 1 在副作用方面几乎等同于x = x += 1(对 x 的修改)。 x = x += 1 等价于 C 中的 x = ++x。这个表达式是 well-known undefined expression

阅读更多信息[here]

【讨论】:

  • 根据C标准“更新左操作数的存储值的副作用是在左操作数和右操作数的值计算之后排序的。”。并且“3 如果存储在一个对象中的值是从另一个对象中读取的,该对象以任何方式与第一个对象的存储重叠,那么重叠应该是准确的,并且两个对象应该具有兼容类型的合格或不合格版本;否则,行为未定义。”。因此,这个表达式是明确定义的。
  • @Vlad 是的,副作用是在计算之后排序的。但是,C 标准还规定“在前一个和下一个序列点之间,一个标量对象的存储值最多只能通过表达式的评估修改一次。”在这个表达式中,x两个 副作用。在我看来,您的第二个引用完全无关紧要。
猜你喜欢
  • 1970-01-01
  • 2016-12-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多