与えられた...
int a = 1, b = 4;
それで...
a += b += a += b;
C++で評価されます...
(a += (b += (a += b))); // a = 14[5 + 9] (b = 9[4 + 5] (a = 5[1 + 4]))
...そしてC#で...
(a += (b += (a += b))); // a = 10[1 + 9] (b = 9[4 + 5] (a = 5[1 + 4]))
// ^ re-use of original value of a (1)
// instead of expected intermediate right-to-left
// evaluation result (5)
上記はVisualStudio2008と2012の両方でテストされているため、最近導入された言語のバグの疑いはありません。
ただし、C#の動作がC ++の動作を模倣することを期待しており、教育が必要であると想定していました。式評価ロジックの方法を理解しているので、MSILを説明する必要はありません。かなり広範囲に検索し、言語仕様で関連する細かい印刷物を見つけることができなかったので、言語の専門家がなぜそうなのかを説明してくれることを望んでいました。
そして、なぜ地球上でこれをやりたいのか知りたい好奇心旺盛な人のために...このような2つの整数型の非常に効率的で整頓されたインラインスワップのための便利な小さなC++トリックがあります...
a ^= b ^= a ^= b;
私はそれがC#で機能しないことに失望し、その理由について興味があります。これは、C#の低レベルのメカニズムとその背後にある理論的根拠を理解することについてです。これ以上、それ以下、特に読みやすさの宗教はご遠慮ください。
NB
皆さん、どうぞ、これはすべてを1行にまとめるという深刻な努力ではありません!!!
C(およびそれ以降のC ++)の場合、演算子の優先順位と結合性は常に正確に定義されています。代入演算子の標準的な右から左への結合性により、C / C ++バージョンの動作が100%明確で予測可能になります。それはいくつかのコンパイラとプラットフォームで私のために働きました、そして私はこのように振る舞わなかったコンパイラが故障していると思います。
コードの行が難読化されていることを認めます。これは好奇心であり、ジュニアC /C++プログラマーに提供する可能性のある「頭の体操」として使用されます。明らかにC#は異なります-そして明らかに意図的にそうです。
私は、C#の祖先言語の1つからの動作の相違につながった設計上の考慮事項の説明を求めています。知識に基づいた推測でも歓迎されます。
AlexanderStepaniuk
に感謝します。
オペランドの左から右への評価から始めます
a = 1 + theRest1 // (1)
theRest1 = b = 4 + theRest2 // (2)
theRest2 = a = 1 + 4 // (3)
(3) into (2): theRest1 = b = 4 + 5
(2) into (1): a = 1 + 9
「なぜ」の説明はまだありがたいです。
しかし、C#仕様は、上記が正しい評価であることを明確にしています。
そして、以下は、C ++のトリックに2つの変数を使用して(私が思うに)得ることができる限り近いです...
b ^= a ^= b;
a ^ = b;
私はそれが好きではありません-記録のために-それは私の直感を壊すので;-)