次のコードを C++ と C# の両方で記述しています。
int i=0;
++i = 11;
このC#コンパイラがエラーを引き起こした後
The left-hand side of an assignment must be a variable, property or indexer
しかし、C++ コンパイラはこのコードをエラーなしで生成し11
、値 の結果を得ましたi
。この違いの理由は何ですか?
次のコードを C++ と C# の両方で記述しています。
int i=0;
++i = 11;
このC#コンパイラがエラーを引き起こした後
The left-hand side of an assignment must be a variable, property or indexer
しかし、C++ コンパイラはこのコードをエラーなしで生成し11
、値 の結果を得ましたi
。この違いの理由は何ですか?
違いは、プレインクリメント演算子はC++ では左辺値であり、C# にはありません。
C++ では++i
、インクリメントされた変数への参照を返します。C# では++i
、変数 i のインクリメントされた値を返します。
この場合、C++ では++i
左辺値、C#では右辺値です。
プレフィックスインクリメント演算子に関するC++仕様から
オペランドの型は、算術型または完全に定義されたオブジェクト型へのポインターでなければなりません。値はオペランドの新しい値です。それは左辺値です。
PS後置インクリメント演算子 i++ は C# と C++ の両方で左辺値ではないため、このコード行は両方の言語でエラーを引き起こします。
int i=0;
i++ = 11;
++i = 11
C++03 では undefinedを呼び出すことに注意してください。これはi
、シーケンス ポイントを介在させずに 2 回変更しているためです。ただし、C++11 では明確に定義されています。最初にインクリメント、次に代入です。
C# と C++ は、2 つのまったく異なる言語と概念です。構文がCに基づいているため、名前のみを共有しています。したがって、実際には「これがC#では機能するのにC ++では機能しない理由」という質問は意味がありません。テーブルが英語では「テーブル」と呼ばれるのに、スペイン語では「メサ」と呼ばれる理由と同じです。こうなると決めていたからです。
C# では、このような構文は許可されていません。
C++ では、次のことが許可されています: 最初++i
に が計算され、 が作成i = 1
され、次に に 11 が割り当てられi
、 が作成されますi = 11
。
セマンティクスは大きく異なります。c++ では、i で識別される格納場所に値 11 を割り当てるというセマンティクスがあります。C# では、セマンティクスは以下のステートメントのセマンティクスと同じです
1=11
つまり、C# コンパイラが許可しない値 1 に値 11 を代入しようとするのと同じです。(Fortran コンパイラは実際にこれを許可しており、地獄のようなデバッグ シナリオを作成する可能性があります)