Как компилятор интерпретирует преинкремент / декремент и постинкремент / декремент - PullRequest
0 голосов
/ 30 июня 2011

Когда кто-то спрашивает о разнице между постинкрементом / декрементом и преинкрементом / декрементом, обычно ответ заключается в том, что префиксные версии добавляют единицу к переменной и возвращают новое значение переменной, тогда как постфиксные версии добавляют ее к переменная и вернуть старое значение.

Пока возился, я обнаружил, что все эти строки законны:

int i = 1;
++i;
++++++++++++++i;
(++++++++++++++i)++;
(++++++(++++(++i)))++;
------i;
--++++--++----++i;
i+=++++++++++++++i+i++-i--; 

Но ни одна из следующих строк не является законной:

i++++;
++i++;
--i--;

Если я предполагаю, что префиксные версии возвращаются по ссылке, это все имеет смысл (даже последний пример, потому что постфикс имеет более высокий приоритет, чем префикс).

Является ли предположение / реализация того, что префиксные версии возвращают ссылку, а постфиксные версии возвращают правильное значение? Существуют ли какие-либо тонкие различия в поведении, о которых я не знаю, для операторов pre / post inc / decment?

Ответы [ 4 ]

2 голосов
/ 30 июня 2011

Все это законно:

Нет, это не законно.Запись переменной более одного раза таким способом является неопределенным поведением.Это синтаксически правильно, и оно будет компилироваться, но это, конечно, не законно.

1 голос
/ 30 июня 2011

В C ++ префиксные выражения приращения / уменьшения «возвращают» lvalues, а версии с постфиксом возвращают rvalue. В C обе формы возвращают значения.

Однако имейте в виду, что поведение не определено, если вы пытаетесь записать переменную более одного раза между двумя точками последовательности. Так что в любом случае это различие не имеет значения.

0 голосов
/ 30 июня 2011

Предположение / реализация того, что префиксные версии возвращают ссылку, а постфиксные версии возвращают правильное значение

Нет.Почему ты так считаешь?Это встроенный оператор, и компилятор может реализовать его по своему усмотрению.

Ваши «допустимые» примеры могут компилироваться, но приводят к неопределенному поведению, потому что вы читаете и пишете в одну и ту же переменную несколько раз без точки последовательности.

0 голосов
/ 30 июня 2011

На ум приходит общая ошибка кодирования: использование переменной, по крайней мере, два раза в одном и том же операторе, при этом, по крайней мере, один экземпляр применяет приращение до / после:

i = i++;
...