0

重複の可能性:
単一ステートメント内の複数のインクリメント演算子
未定義の動作とシーケンス ポイント

このコード行がそのような出力を生成する理由を誰かが説明できますか? コード (i&j の両方をゼロに初期化した後):

cout<<i++<<','<<++j<<','<<--i<<','<<j--<<'\n';

出力:

-1,0,0,0;

i++ は最初に評価してから 1 ずつ増やすことを意味し、++i は 1 ずつ増やしてから評価することを意味します。しかし、シーケンスされた cout ステートメントでの複数の評価がどのような動作であるかはわかりません。

ありがとう!

4

2 に答える 2

6

そのコードの動作は未定義です。実装は、 のi++--iまたは後に評価することも、最終結果がまったく意味をなさないように評価をずらすこともできます。

次のようなコードに直面した場合、オプティマイザーにとっても合法です。

if( k != 0 ) {
   cout << i++ << --i;
}
foofum(k);

then 分岐のコードは未定義の動作であるためそれは常にゼロであると結論付けてk、全体を

foofum(0);

(これは、順序付けされていない更新の「未定義」の動作が、iたまたま閉じ括弧に 0 を割り当ててkジャンプする可能性があるという事実によって正式に正当化されます。未定義は、実際には何でも起こり得ることを意味します)。

そのようなコードを書かないでください。

編集:<<削除された回答では、オーバーロードされたはネイティブ演算子ではなく関数呼び出しであるため、ステートメントの効果は単に指定されていないことが示唆されました。ただし、それはステートメントを同等にするだけであり、現在の目的では、

f(g(i++), i--);

(ここで、fは 1 つの引数を表しますが、とostream::operator<<()の評価順序の規則は同じです)。コンパイラは、 への引数を評価する順序を決定できます。たまたま最初に評価された場合、評価順序は次のようになります。AAA.f(BBB)f(AAA,BBB)fi--

  • i--
  • i++
  • シーケンスポイント
  • 電話g
  • シーケンスポイント
  • 電話f

i--とを区切るシーケンス ポイントがないためi++、未定義の動作が発生します。

一方、f(g(i+=h()), i++)シーケンスポイント形式の下では、間違いなく単に指定されていません。C++1x の関係式では undefined に戻ると思います。

于 2011-08-29T16:23:03.110 に答える
2

C/C++ の関数に対する引数の評価順序はUnspecifiedです。
引数が渡される順序は<<ここでは指定されていないため、結果になります。

于 2011-08-29T16:25:50.893 に答える