【问题标题】:Undefined behaviour rules for i = ++i and the likei = ++i 等的未定义行为规则
【发布时间】:2015-09-18 15:55:55
【问题描述】:

我一直在复习我未定义的行为规则,并阅读以下内容:

Undefined behavior and sequence points
Why is f(i = -1, i = -1) undefined behavior?
Why is `x-- > 0` not undefined behaviour, while `x = x--` is?

并且 In C++11, does `i += ++i + 1` exhibit undefined behavior?

最后问了三个问题:

  1. i=i++ 形式的术语的未定义行为规则是否适用于非整数类型? (表达式应该翻译成i.operator(i.operator++(i)),由于每个函数调用都是一个序列点,如果我正确理解标准,它应该被很好地定义)
  2. 为什么f(i=-1, i=-1)未定义行为与“赋值操作的结果是赋值后存储在左操作数中的值;结果是左值”(参考)[https://stackoverflow.com/a/4190054/258418]? (我知道之后 i 的值是未定义的,但如果我正确理解标准,函数调用应该被评估为f(-1, -1)
  3. 哪些类型的表达式在 c++11/14/1z 中变得安全,只有简单赋值中的预增量/预减量(没有 op=)?

【问题讨论】:

  • 为什么你们这些疯狂的人都坚持写这样的怪物:'(
  • #3 中的“变得安全”是什么意思?
  • @Quentin:我不坚持写这些 montrosities,我可能永远不会靠近它们(我可能写过类似 i=(++i)*x 而不是 i=(i+1)*x 一次,但为了避免这种情况我需要a)意识,b)确保前者是危险的(我同意大多数例子都是丑陋的/构造的)。
  • @interjay:抱歉,我跳过了提到新 c++ 标准的部分(据我所知,c++11 发生了变化)
  • @ted 别担心,你的问题是一个很好的问题(我赞成),我只是在开玩笑说序列点触发行为正在变成的运行噱头的长度,即使没有真正使用这样的结构会受益匪浅:)

标签: c++ language-lawyer


【解决方案1】:

忘记f (i = -1, i = -1)。假设你有两个指针int* pint* q,你调用

f (*p = 1, *q = 2)

如果 p == q,这是未定义的行为。如果您不希望它是未定义的行为,那么在 p == q 的情况下您将如何定义行为? (因为如果你不喜欢它是未定义的,你必须以某种方式定义它)。此外,您是否会接受这样的行为定义,即 99.999% 的代码运行速度可能会慢一些,以节省一些明显愚蠢的代码?

接下来就是这样了

f (*p = -1, *q = -1)

因此分配了相同的值。如果您希望将其定义为行为,但不分配不同的值,那么您究竟如何建议将其纳入明智的规则?

【讨论】:

  • 我并不是说这是有道理的,我们有 restrict 关键字是为了速度的原因。 (我们实际上将指针传递给函数)。我更多地认为,由于= 返回赋值的值,所以应该使用正确的参数调用该函数。至于下一条语句的pq 的定义,我仍然和你在一起。
  • @ted 你是什么意思?您是否希望在不进行分配的情况下调用该函数?
猜你喜欢
  • 1970-01-01
  • 2017-02-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-03
  • 1970-01-01
相关资源
最近更新 更多