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