Никакой.
Фрагмент n[i++] = n[i] провоцирует неопределённое поведение, так как операция приравнивания не является точкой следования.
Это значит, что оператор волен выбирать, какое именно выражение надо вычислять первее: n[i++] или n[i]. Единственное ограничение — к моменту присваивания оба фрагмента должны дать по значению (ссылку и число соответственно).
Неопределённое поведение следует из того, что компилятор рассматривает обе части независимо. Соответственно, i++ из левой части и i из правой друг с другом как бы не связаны. Мало того, что чтение-изменение-запись постинкремента может быть переставлено местами с просто чтением, так они могут быть ещё и перемешаны друг с другом.
На большом StackOverflow уже был задан вопрос о том, почему присваивание не является точкой следования:
Имеется ли какое-нибудь обоснованию тому, что оператор = не является точкой следования как в Си, так и в C++?
Нужна веская причина для того, чтобы что-то стало точкой следования. В причинах же того, чтобы этого не делать, нужды нет — это вариант по умолчанию.
К примеру, && должен быть точкой следования из-за short-circuiting: если левая часть оператора ложна, правая его часть вычислена не будет. Это связано не столько с оптимизацией, сколько с возможностью создания зависимости правой части от левой (к примеру, в ptr && ptr->data). Поэтому левая часть обязательно должна быть вычислена строго до правой, чтобы знать, надо ли вычислять правую часть вообще.
В случае же с = подобной причины не существует. Хотя этот оператор и является присваиванием (...), точный порядок вычисления сторон не имеет значения, пока они выполняются до собственно присваивания.
P. S. Кстати, проблема с ++i + ++i имеет такую же первопричину.
warning: unsequenced modification and access to 'i' [-Wunsequenced]думаю это всё же UB. – pavel Jan 18 '17 at 12:08