Полная история.В C99 у нас был этот текст для 6.5.16 оператора присваивания:
Побочный эффект обновления сохраненного значения левого операнда должен иметь место между предыдущей и следующей точкой последовательности.
Порядок оценки операндов не указан.Если предпринята попытка изменить результат оператора присваивания или получить к нему доступ после следующей точки последовательности, поведение не определено.
Это было изменено в C11 на:
Побочный эффект обновления сохраненного значения левого операнда секвенируется после вычислений значения левого и правого операнда.Оценки операндов не секвенированы.
Это просто разные (и хуже) формулировки, две версии ведут себя одинаково - ключ является последним предложением в части C11, который все еще делает это неопределенное поведение, поскольку оценка левого операнда все еще не секвенирована относительно правого операнда.Вычисление значения относится только к отдельным операндам.
C17 имеет такой же текст, как C11.Таким образом, ответ: нет, i = i++;
все еще неопределенное поведение в C17.
Просто для сравнения, сравните это с C ++ 11 (5.17):
Во всех случаях присвоение упорядочивается после вычисления значения правого и левого операндов и до вычисления значения выражения присваивания.
Это примерно тот же текст, что и C11, без явного«оценки операндов не последовательны».Это было изъяном в C ++ 11, неясно, сделало ли это определенные выражения четкими или нет.
C ++ 17 дает пояснение (8.5.18):
Во всех случаях присвоение упорядочивается после вычисления значения правого и левого операндов и до вычисления значения выражения присваивания.Правый операнд упорядочен перед левым операндом.
Так что в C ++ 17, i=i++;
определенно четко определен.И, как мы видим, формулировка является явной, в отличие от «непоследовательности» в C11 / C17.