#ИМЯ?
Ниже код дает ошибку при компиляции в компиляторе C
++(-i);
error: lvalue required as increment operand
Это означает, что -i возвращает rvalue.
в то время как код
++(+i);
не дают никаких ошибок. Почему так? эта ссылка говорит, что + я не приводит к lvalue.
Ответы
Ответ 1
Это сбой в вашем компиляторе. В языке C все lvalues в выражениях преобразуются в значения r даже до применения любых операторов, за исключением операндов sizeof
, &
, ++
, --
и левых сторон .
и присвоения (см. 6.3.2/2)
Другими словами, на языке C +i
должен выдавать rvalue не потому, что унарный +
предположительно создает rvalue, а скорее потому, что i
преобразуется в rvalue, прежде чем этот унарный +
даже получит шанс сделать его вещь.
Например, для переменной int i
, которая содержит значение 42
, выражение +i
полностью эквивалентно выражению +42
. Плотность i
теряется, и она превращается в 42
, прежде чем вступает в действие семантика унарного +
.
Излишне говорить, что в этом случае нет шанса, что результатом унарного +
может быть lvalue.
Ответ 2
Из стандарта C99 (6.5.3.3 Унарные арифметические операторы):
2 Результатом унарного + оператора является значение его (продвинутого) операнда. Целые рекламные акции выполняются в операнде, и результат имеет продвинутый тип.
3 Результат унарного оператора является отрицательным его (продвинутым) операндом. Целые рекламные акции выполняются в операнде, и результат имеет продвинутый тип.
В этом конкретном контексте нет кода, который использовал бы продвинутое значение +i
, поэтому я считаю, что ваш компилятор предполагает, что он эквивалентен i
, и по этой причине он обрабатывает это значение lvalue. Или, может быть, просто он вообще не реализует унарный +
. Во всяком случае, это не то, что вы должны делать вообще, а другие компиляторы просто запретят это.
-i
выполняет фактическую операцию, поэтому ее результат является временным. Таким образом, вы не можете увеличивать его, потому что это не переменная больше.
И стандарт делает это понятным в 6.3.2.1 Другие операнды /Lvalues, массивы и обозначения функций:
2 За исключением случаев, когда это операнд оператора sizeof, унарный и оператор, оператор ++, оператор-оператор или левый операнд. оператора или оператора присваивания, значение l, которое не имеет типа массива, преобразуется в значение, хранящееся в указанном объекте (и больше не является lvalue). [...]