【问题标题】:Is f(++i, ++i) undefined?f(++i, ++i) 是未定义的吗?
【发布时间】:2017-09-07 03:31:12
【问题描述】:

我似乎记得在 C++11 中,他们对排序行为进行了一些更改,现在 i++ 和 ++i 有不同的排序要求。

f(++i, ++i) 仍然是未定义的行为吗? f(i++, i++)f(++i, ++i)有什么区别?

【问题讨论】:

  • 谁在乎?这是愚蠢的行为。
  • 我猜language-lawyer 在这里很合适。
  • 天哪....这实际上是一个标签:|
  • 由于 [intro.execution]/15 中的示例明确将 f(i = -1, i = -1); 称为 UB,因此问题的答案(对于标量 is)应该是显而易见的。
  • 这个问题会在这里问多少次???

标签: c++ language-lawyer


【解决方案1】:

除非i 是类类型,否则这是未定义的行为。从 C++11 1.9/15 开始:

除非另有说明,否则单个运算符的操作数和单个表达式的子表达式的求值是无序的。

后跟注释说明这确实适用于函数参数:

[ 注意: 与不同参数表达式相关的值计算和副作用是无序的。 ——尾注 ]

您的代码在没有排序的情况下修改了同一个对象两次,因此在同一个段落中:

如果标量对象的副作用相对于同一标量对象的另一个副作用或值计算是无序的 使用相同标量对象的值,行为未定义

如果i 是一个类类型,那么++ 将调用一个函数,并且函数调用总是相对于彼此进行排序。因此,任何对标量对象的修改都将是不确定的;没有未定义的行为,但结果未指定。

【讨论】:

    【解决方案2】:

    它仍然是未定义的行为:

    如果标量对象的副作用相对于同一标量对象的另一个副作用或使用同一标量对象的值的值计算是无序的,则行为未定义。

    §1.9 [intro.execution]

    并且函数参数的评估顺序相对于彼此是无序的。

    【讨论】:

      【解决方案3】:

      在 C++17 中,它不是未定义的。 http://en.cppreference.com/w/cpp/language/eval_order#Undefined_behavior

      f(++i, ++i); // 在 C++17 之前未定义的行为,在 C++17 之后未指定

      在函数调用中,每个参数初始化的值计算和副作用相对于任何其他参数的值计算和副作用是不确定的。

      【讨论】:

      • 添加到这个答案:代码int i = 0; f(++i, ++i) 将导致i == 2f 使用以下任何参数组合调用:(1, 1), (1, 2), (2, 1), (2, 2)
      • @Revolver_Ocelot,我认为只有f(1, 2)f(2, 1)的调用符合C++17标准,因为两个参数初始化的值计算和副作用不应该重叠。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-05-19
      • 2013-07-03
      • 2011-04-25
      • 2014-01-28
      • 2015-09-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多