x
シーケンスポイント間で2回変更されるため、未定義です。標準では、定義されていないため、定義されていません。
それだけ知っています。
しかし、なぜ?
私の理解では、これを禁止することで、コンパイラーの最適化が向上します。Cが発明されたとき、これは理にかなっていたかもしれませんが、今は弱い議論のように思えます。
今日Cを再発明する場合、この方法でそれを行うのでしょうか、それとももっと良くすることができますか?
または、より深い問題があり、そのような式に一貫したルールを定義するのが難しくなるので、それらを禁止するのが最善ですか?
したがって、今日Cを再発明するとします。のような式の単純なルールを提案したいのx=x++
ですが、これは既存のルールよりもうまく機能しているように思えます。
提案されたルールを既存のルールと比較したり、他の提案について意見を聞きたいと思います。
推奨ルール:
- シーケンスポイント間では、評価の順序は指定されていません。
- 副作用はすぐに起こります。
関連する未定義の動作はありません。式はこの値またはそれを評価しますが、確かにハードディスクをフォーマットしません(奇妙なことに、x=x++
ハードディスクをフォーマットする実装を見たことはありません)。
式の例
x=x++
-明確に定義され、変更されませんx
。
最初に、x
(x++
評価されるとすぐに)インクリメントされ、次に古い値がに保存されx
ます。x++ + ++x
-2x
回インクリメントし、評価され2*x+2
ます。
どちらかの側が最初に評価されますが、結果はx + (x+2)
(左側が最初)または(x+1) + (x+1)
(右側が最初)です。x = x + (x=3)
-指定なし、またはにx
設定。 右側が最初に評価される場合、それはです。最初に評価される可能性もあるため、です。どちらの場合でも、評価は評価されるとすぐに行われるため、保存されている値は他の割り当てによって上書きされます。x+3
6
x+3
x=3
3+3
x=3
x=3
x+=(x=3)
-明確に定義され、x
6 に設定されます。
これは、上記の表現の単なる省略形であると言えます。
ただし、2つの部分(読み取り、評価、追加、新しい値の保存)ではなく、の+=
後x=3
に実行する必要があります。x
x=3
利点は何ですか?
いくつかのコメントはこの良い点を提起しました。
私は確かに、そのような表現x=x++
は通常のコードで使用されるべきだとは思いません。
実は、私ははるかに厳しいものよりだ-私はのための唯一の良い使い方を考えるx++
ようでx++;
一人で。
ただし、言語のルールはできるだけシンプルでなければなりません。それ以外の場合、プログラマーはそれらを理解しません。シーケンスポイント間で変数を2回変更することを禁止する規則は、ほとんどのプログラマーが理解していない規則です。
非常に基本的なルールは次のとおり
です。Aが有効で、Bが有効であり、それらが有効な方法で結合されている場合、結果は有効です。
x
は有効なL値でx++
あり、有効な式であり=
、L値と式を組み合わせる有効な方法x=x++
です。
C標準はここで例外を作成し、この例外はルールを複雑にします。stackoverflow.comを検索して、この例外がユーザーをどれほど混乱させるかを確認できます。
だから私は言う-この混乱を取り除く。
===回答の要約===
どうしてですか?
上記のセクションで説明しようとしました-Cルールをシンプルにしたいのです。最適化の可能性:
これはコンパイラーからある程度の自由を奪いますが、それが重要であると私に納得させるものは見ませんでした。
ほとんどの最適化は引き続き実行できます。たとえばa=3;b=5;
、標準で順序が指定されていても、並べ替えることができます。などの式もa=b[i++]
同様に最適化できます。既存の標準を変更することはできません。
認められない、できない。規格やコンパイラを実際に変更できるとは思っていませんでした。物事が違ったやり方でできたのかどうかを考えたかっただけです。
x
それ自体に割り当てることはあまり意味がなく、増分したいx
場合は、単に言うことができますx++;
-割り当ての必要はありません。何が起こるかを思い出すのが難しいという理由だけで、定義すべきではないと言います。