Является ли * 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 может увеличиваться в любое время.