5

私はこの記事を読みました:未定義の動作とシーケンスポイントですが、それが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

この動作についての情報を教えてください。

4

2 に答える 2

10

の引数評価の順序a + b + cはコンパイラ固有です。したがって、への呼び出しの順序はx++コンパイラ固有であり、それを中継することは未定義の動作になります。

x++このような式でまたはを使用++xすることは、通常、コーディング標準が不適切であることを示しています。それを避けて、表現を単純化することをお勧めします。

この質問では、コンパイラとC ++での引数の評価順序について、C++での引数の評価順序に関する説明を見つけることができます。

C++標準への参照を含むC++評価順序の説明は次のとおりです。http://en.cppreference.com/w/cpp/language/eval_order

PS Bjarne Stroustrupは、「C++プログラミング言語」第3版のセクション6.2.2で明示的に述べています。彼はまた理由を与えます:

式の評価順序に制限がない場合は、より適切なコードを生成できます。

https://stackoverflow.com/a/2934909/1065190から)

于 2012-11-12T12:41:54.713 に答える
9

のpost-incrementsの間にシーケンスポイントがないため、これは未定義の動作ですx。どちら+が最初に評価されるか、どちらop(x++)が最初に構築されるか、どの順序x++で実行されるかはわかりません。それは未定義です、ただそのようなコードを書かないでください。

于 2012-11-12T12:38:00.253 に答える