Является ли * p ++ + = 2 четко определенным?
Я не уверен, что инструкция ниже хорошо определена стандартом C или нет
*p1++ += 2;
или другое подобное утверждение:
*E1++ <operator>= E2
Из стандартного C о пост-приращении:
Результатом оператора postfix ++ является значение операнда. После того, как результат будет получен, значение операнда будет увеличено. (То есть к нему добавляется значение 1 соответствующего типа.) См. обсуждение аддитивных операторов и составное назначение для информацию об ограничениях, типах и преобразованиях и операции над указателями. Побочный эффект обновления сохраненного значения Операнда происходит между предыдущей и следующей последовательностью точка.
И о присвоении coumpund:
Составное присвоение формы E1 op = E2 отличается от простого выражение E1 = E1 op (E2) только в том смысле, что lvalue E1 является оценивается только один раз.
Ответы
Ответ 1
Перепишите немного, чтобы сделать его более понятным:
(*p1++) += 2
Таким образом, старое значение p1
будет разыменовано, и 2 будет добавлено к его референту. И p1
будет увеличиваться после разыменования (или, по крайней мере, после того, как его старое значение будет загружено и ожидает разыменования). Здесь нет проблем: ни одна из частей не используется более одного раза.
При этом вы должны подумать о том, чтобы переписать код для ясности:
*p1 += 2;
++p1;
Ответ 2
Оператор приращения Postfix (++
) дает значение операнда, то есть дает r-значение. Значение r подразумевает, что он будет использоваться слева от оператора присваивания (=
) в качестве операнда.
int i = 0;
i++ = 0 // [Error] lvalue required as left operand of assignment
В случае
*p1++ += 2;
postfix ++
не применяется к *p1
, но применяется к указателю p1++
. Это связано с тем, что постфикс ++
имеет более высокий приоритет, чем у оператора derereference *
. Итак, компилятор проанализирует вышеуказанный оператор как
*(p1++) += 2;
и это говорит о том, что:
-
*p1
должен быть оценен (для создания переменной) перед добавлением 2
и присвоением ему результата.
- Результат, который нужно сохранить в
*p1
, должен быть оценен до инкремента до p1
.
- После оценки
*p1
p1
может увеличиваться в любое время.