Подтвердить что ты не робот

#ИМЯ?

Ниже код дает ошибку при компиляции в компиляторе C

++(-i);
error: lvalue required as increment operand

Это означает, что -i возвращает rvalue.

в то время как код

++(+i);

не дают никаких ошибок. Почему так? эта ссылка говорит, что + я не приводит к lvalue.

4b9b3361

Ответ 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). [...]