«В любом случае, следуйте рекомендациям: предпочитайте ++ i над i ++, и вы не ошибетесь». В чем причина этого в C?

Я наткнулся на этот ответ на этот вопрос. В одной из строк автор упоминает:

В любом случае следуйте принципу «предпочитайте ++i i++», и вы не ошибетесь.

Я знаю, что ++i немного быстрее, чем i++, но подумал, что у них нет причин ошибаться. Некоторое время я искал, и ближе всего я смог найти это . Он четко объяснил, почему предпочтительнее использовать ++i, но не все же, как вы могли ошибиться, используя i++.

Так может ли кто-нибудь сказать мне, как i++ может пойти не так?

ПРИМЕЧАНИЕ. Мой вопрос не обман, так как я не спрашиваю о производительности. Я уже видел этот вопрос. Я спрашиваю, как i++ может ошибаться, как упомянуто в ответе, который я упомянул выше.


person Ashish Ahuja    schedule 26.02.2016    source источник
comment
Это не немного быстрее; любой, кто говорит вам это, понятия не имеет, о чем они говорят.   -  person R.. GitHub STOP HELPING ICE    schedule 26.02.2016
comment
@R .., но вы это даже написали в вопросе, который я связал. Написано, что это быстрее, потому что i++ должен хранить старое значение, а ++i нет. Таким образом экономится время на его хранение. См .: Есть ли разница в производительности между i ++ и ++ i в C?   -  person Ashish Ahuja    schedule 26.02.2016
comment
@AshishAhuja Хотя исторически существовали незначительные различия в производительности, современные компиляторы настолько хороши в обнаружении и удалении мертвого кода, что я был бы удивлен, если бы это действительно стало проблемой.   -  person templatetypedef    schedule 26.02.2016
comment
@AshishAhuja: Заявление неверно. Сохранение старого значения не происходит.   -  person R.. GitHub STOP HELPING ICE    schedule 26.02.2016
comment
Даже если дело не в производительности, я думаю, что (логическая) разница между ++i и i++, должно быть, обсуждалась миллионы раз ...   -  person Nicolas Miari    schedule 26.02.2016
comment
@AshishAhuja В приведенном вами ответе также говорится, что ++ i кажется более распространенным, возможно, потому, что это то, что используется в K&R. Но на самом деле беглый взгляд на второе издание K&R показывает, что в книге используются оба стиля , причем i++ является более распространенным. И i++ используется в разделе 3.5, где формально представлен цикл for. Поэтому я думаю, что приведенный вами ответ немного предвзят, и автор просто продвигает свой предпочтительный стиль.   -  person user3386109    schedule 26.02.2016
comment
@Barmar, это не обман.   -  person Qix - MONICA WAS MISTREATED    schedule 26.02.2016
comment
Я спрашиваю, как я ++ могу ошибаться, как упомянуто в ответе, который я упомянул выше. Единственный человек, который может ответить на ваш вопрос, - это Марк Харрисон, поскольку он написал ответ, который вы процитировали. Он также написал вопрос и ответ, процитированный Бармаром. В этом вопросе и ответе он не только сказал, что нет разницы в производительности, но и что компилятор генерирует идентичный код. Так что этот вопрос следовало задать в качестве комментария под его ответом.   -  person user3386109    schedule 26.02.2016
comment
Под «ошибкой» автор сообщения явно имел в виду написание неэффективного кода. Так что да, это дубликат, даже если вы не понимаете.   -  person Lundin    schedule 26.02.2016
comment
Как правило, миф о том, что ++ i быстрее, восходит к C ++, где иногда это правда, поскольку в этом языке есть перегрузка операторов.   -  person Lundin    schedule 26.02.2016
comment
@Lundin, как перегрузка оператора связана с постом и предварительным приращением?   -  person Ashish Ahuja    schedule 26.02.2016
comment
@AshishAhuja Потому что, если вы перегрузите оператор postfix ++ в C ++, произойдет вызов функции и внутри нее будет создана временная копия этого объекта. Пример кода.   -  person Lundin    schedule 26.02.2016
comment
На самом деле array [i ++] может быть немного быстрее, чем array [++ i]. Причина в том, что на суперскалярных (например, современных процессорах Intel) вычисление приращения и адреса может выполняться параллельно с первым, но не с последним. Это называется параллелизмом на уровне инструкций.   -  person Eloff    schedule 26.02.2016
comment
@Eloff: Это неправда. array[++i] эквивалентно (array+1)[i++], и последнее в равной степени может выполняться параллельно.   -  person R.. GitHub STOP HELPING ICE    schedule 04.03.2016


Ответы (1)


В случае

for (i=start; i<end; i++)

vs

for (i=start; i<end; ++i)

их значения полностью идентичны, потому что значения выражений i++ и ++i не используются. (Они оцениваются только на предмет побочных эффектов.) Любой компилятор, который производит различный код для этих двух, является патологически плохим, и его следует выбросить в мусор. Здесь используйте любую форму, которую вы предпочитаете, но i++ является идиоматикой среди программистов на C.

В других контекстах используйте форму, которая дает желаемое значение. Если вы хотите получить значение до приращения, используйте i++. Это имеет смысл для таких вещей, как:

index = count++;

or

array[count++] = val;

где старое значение count становится индексом нового слота, в котором вы собираетесь что-то хранить.

С другой стороны, если вы хотите получить значение после увеличения, используйте ++i.

Обратите внимание, что для целочисленных типов все следующие полностью эквивалентны:

  • i += 1
  • ++i
  • i++ + 1

и аналогично следующие эквиваленты:

  • (i += 1) - 1
  • i++
  • ++i - 1

С плавающей запятой и указателями все сложнее.

Что касается каких-либо объективных причин, то найденный вами совет - нонсенс. Если же, с другой стороны, вы находите, что ++i легче рассуждать, не стесняйтесь прислушиваться к совету, но это будет полностью зависеть от человека и того, к чему вы привыкли.

person R.. GitHub STOP HELPING ICE    schedule 26.02.2016
comment
Вы рассеиваете все мои сомнения. просто вы хотите сказать, что @MarkHarrison ошибается, и на самом деле нет разницы между i++ и ++i? - person Ashish Ahuja; 26.02.2016
comment
@AshishAhuja Этот ответ в значительной степени идентичен этому, опубликованному мной в связанном дубликате. - person Lundin; 26.02.2016