这是未指定(未定义的)行为

Is this unspecified (undefined) behaviour or not?

本文关键字:行为 未定义 未指定      更新时间:2023-10-16

我已经阅读了本文:未定义的行为和序列点,但我无法弄清楚它是否是ub。

考虑,以下示例:

#include <iostream>
class op {
public:
  explicit op(int x) {
    std::cout << "x:   " << x << std::endl;
  }
  op & operator + (const op & /* other */) {
    return *this;
  }
};
int main(int /* argc */, char * /* argv */ []) {
  int x = 0;
  op o = op(x++) + op(x++) + op(x++);
  std::cout << "res: " << x << std::endl;
  return 0;
}

我期望这样的输出(或根据评估顺序取消输出的某些输出):

x:   0
x:   1
x:   2
res: 3

GCC-4.7.1和Clang-3.0给我这样的输出,但是当我使用MSVC-2010编译此示例时,我已经输出了:

x:   0
x:   0
x:   0
res: 3

您可以给我一些有关此行为的信息。

a + b + c中参数评估的顺序是编译器特定的。因此,拨打x++的呼叫顺序将是特定于编译器的,并且中继将是未定义的行为。

在此类表达式中使用x++++x通常是不良编码标准的迹象。最好避免它并简化您的表达方式。

在此问题编译器和C 评估的论点顺序中,您可以在C 中找到有关参数评估顺序的讨论。

这是C 评估顺序的解释,其中包括C 标准的引用:http://en.cppreference.com/w/cpp/language/eval_order

p.s。 bjarne stroustrup在" C 编程语言"中明确表示,第3版第6.2.2节。他还提供了一个原因:

在没有表达评估顺序的限制的情况下,可以生成更好的代码。

(来自https://stackoverflow.com/a/2934909/1065190)

它是未定义的行为,因为 x的后插图之间没有序列。您无法判断哪个+将首先评估,您无法首先构建哪个op(x++),也无法确定将执行x++的顺序。它是不确定的,只是不要写那样的代码。