2014-10-17 2 views
16

Я не уверен, является ли утверждение ниже хорошо определяется стандартом C или неЯвляется ли * p ++ + = 2 четко определенным?

*p1++ += 2; 

или другое подобное заявление:

*E1++ <operator>= E2 

От стандартного C о постинкремента:

Результатом оператора postfix ++ является значение операнда. После того, как результат будет получен, значение операнда будет увеличено. (То есть к нему добавляется значение 1 соответствующего типа.) См. Обсуждения аддитивных операторов и составное назначение для информации об ограничениях, типах и преобразованиях и эффектах операций с указателями. Побочный эффект обновления сохраненного значения операнда должен происходить между предыдущей и следующей последовательностью .

А про coumpund-назначение:

Соединение присвоение вида E1 оп = E2 отличается от простого выражения присваивания E1 = E1 оп (Е2) только тем, что именующее E1 является оценивается только один раз.

+0

Ну, что именно вызвало ваше подозрение, что оно может быть неопределенным? Для меня, например, все выглядит хорошо, что затрудняет мне даже начать отвечать на вопрос: я не знаю, на чем сосредоточиться. – AnT

+2

Dont писать коды в проекте, как это, за исключением исследования на нем. – wshcdr

+9

Написание такого неразборчивого кода, чтобы набрать больше кода на одной строке, - плохое программирование. :) – Almo

ответ

23

Давайте перепишем немного, чтобы сделать его более ясным:

(*p1++) += 2 

Так старое значение p1 будет разыменовании и 2 будут добавлены к его референтом. И p1 будет увеличиваться после разыменования (или, по крайней мере, после того, как его старое значение будет загружено и ожидает разыменования). Здесь нет проблем: ни одна из частей не используется более одного раза.

Это, как говорится, вы должны рассмотреть вопрос переписывания кода для ясности:

*p1 += 2; 
++p1; 
+9

«then» не совсем прав, побочный эффект + = может произойти до или после побочного эффекта ++. Они заключаются в том, что они находятся на разных скалярных объектах. – Cubbi

3

Postfix оператор инкремента (++) дает значение операнда, то это дает г-значение. Значение r означает, что оно должно использоваться слева от оператора присваивания (=) в качестве операнда.

int i = 0; 
i++ = 0 // [Error] lvalue required as left operand of assignment 

В случае

*p1++ += 2; 

постфикса ++ не применяется на *p1, но он применяется к указателю p1++. Это связано с тем, что постфикс ++ имеет более высокий приоритет, чем у оператора derereference *. Таким образом, компилятор будет анализировать приведенное выше утверждение, как

*(p1++) += 2; 

и это говорит о том, что:

  • *p1 должны быть оценены (для получения переменной) перед добавлением 2 и присвоения результата к нему.
  • Результат, который необходимо сохранить до *p1, должен быть оценен до приращения до p1.
  • После оценки *p1p1 может увеличиваться в любое время.
+0

Является ли последнее утверждение гарантированным на C++? – BlueTrin

+0

@BlueTrin; Да. – haccks

+1

Я бы подумал, что после вычисления 'p1'' 'p1' может увеличиваться в любое время. – BlueTrin

Смежные вопросы