Давайте рассмотрим следующий код:
int main() {
int i = 2;
int b = ++i++;
return 3;
}
Он компилирует следующее с ошибкой:
<source>: In function 'int main()':
<source>:3:16: error: lvalue required as increment operand
3 | int b = ++i++;
| ^~
Это звучит справедливо для меня. Приращение постфикса имеет более высокий приоритет, чем приращение префикса, поэтому код анализируется как int b = ++(i++);
и i
является r-значением. Отсюда и ошибка.
Давайте теперь рассмотрим этот вариант с круглыми скобками, чтобы переопределить приоритеты по умолчанию:
int main() {
int i = 2;
int b = (++i)++;
return 3;
}
Этот код компилируется и возвращает 3. Сам по себе, это звучит справедливо для меня, но кажется, что это противоречит первому коду.
Вопрос: почему (++i)
это lvalue
когда i
нет?
Спасибо!
ОБНОВЛЕНИЕ: сообщение об ошибке, показанное выше, было от gcc (x86-64 9.2). Вот точный рендеринг: ошибка с gcc
Clang x86-64 9.0.0 имеет совершенно другое сообщение: ошибка с clang
<source>:3:13: error: expression is not assignable
int b = ++i++;
^ ~~~
С GCC у вас создается впечатление, что проблема в постфиксном операторе, и вы можете узнать, почему ++i
все в порядке, а i
что нет, отсюда и мой вопрос. С Clang становится понятнее, что проблема с префиксным оператором.
Ответы:
i
и++i
оба являются lvalues, ноi++
являются rvalue.++(i++)
не может быть действительным, так как префикс++
прикладывается кi++
, который является Rvalue. Но(++i)++
это хорошо, потому что++i
это lvalue.Обратите внимание, что в C ситуация другая;
i++
и++i
оба значения. (Это пример того, почему люди должны перестать предполагать, что C и C ++ имеют одинаковые правила. Люди вставляют эти предположения в свои вопросы, которые затем должны быть опровергнуты.)источник
Эта декларация
эквивалентно
Оператор постфиксного приращения возвращает значение операнда перед приращением.
Из стандарта C ++ 17 (8.2.6 Увеличение и уменьшение)
В то время как унарный оператор приращения возвращает lvalue после его приращения. Так что эта декларация
действует. Вы могли бы, например, написать
Из стандарта C ++ 17 (8.3.2 Увеличение и уменьшение)
Обратите внимание, что в Си оба оператора возвращают значение вместо lvalue. Так что в C это объявление
является недействительным.
источник
Нет,
i
это не ценность.i
это lvalue.i++
является rvalue (prvalue, чтобы быть конкретным).источник