++ я разность операторов в С# и С++
У меня есть следующий код, написанный как на С++, так и на С#
int i=0;
++i = 11;
После этого компилятор С# приносит ошибку
The left-hand side of an assignment must be a variable, property or indexer
Но компилятор С++ генерирует этот код без ошибок, и я получил результат 11
для значения i
. В чем причина этой разницы?
Ответы
Ответ 1
Разница заключается в том, что оператор pre-increment lvalue в С++ и не находится на С#.
В С++ ++i
возвращается ссылка на добавочную переменную. В С# ++i
возвращает приращение значения переменной i.
Таким образом, в этом случае ++i
lvalue в С++ и rvalue в С#.
Из спецификации С++ о приведении указателя префикса
Тип операнда должен быть арифметическим типом или указателем на полностью определенный тип объекта. Значение - это новое значение операнд; это lvalue.
P.S. Оператор приращения postfix я ++ не является lvalue как в С#, так и в С++, поэтому эти строки кода приведут к ошибке на обоих языках.
int i=0;
i++ = 11;
Ответ 2
Обратите внимание, что ++i = 11
вызывает undefined в С++ 03, потому что вы дважды изменяете i
без промежуточной точки последовательности. Однако он хорошо определен в С++ 11: сначала инкремент, затем назначение.
Ответ 3
С# и С++ - это 2 совершенно разные языки и понятия. Они используют только имя, потому что их синтаксис основан на C. Так что на самом деле "почему это работает на С#, но не на С++" не имеет никакого смысла в качестве вопроса. Это то же самое, что сказать, почему таблица называется "таблица" на английском языке, но "mesa" на испанском языке. Потому что решено было так.
С# просто не допускает такой синтаксис.
В С++ вам разрешено: сначала вычисляется ++i
, что делает i = 1
, а затем 11 присваивается i
, что делает i = 11
.
Ответ 4
семантика очень различна. В С++ семантика состоит в том, что вы присваиваете значение 11 месту хранения, указанному i. В С# семантика равна семантике приведенного ниже выражения
1=11
То есть он равен попытке присвоить значение 11 значению 1, которое компилятор С# не разрешает. (Компиляторы Fortran действительно разрешают это, и это может создавать адские сценарии отладки)