Будет ли я = i ++ заново определен в C17? - PullRequest
0 голосов
/ 25 ноября 2018

После того, как я наткнулся на вопрос " Почему эти конструкции используют неопределенное поведение до и после приращения? " сегодня я решил взять новейший черновик для следующего стандарта C, который могнайдите и прочитайте больше об этом.
Вскоре после того, как я обнаружил следующий абзац в черновике C17:

Выражение - это последовательность операторов и операндов, которая задает вычисление значения или обозначаетобъект или функция, или который генерирует побочные эффекты, или который выполняет их комбинацию. Вычисления значений операндов оператора секвенируются до вычисления значения результата оператора
Источник: ИСО / МЭК 9899: 2017, раздел 6.5 §1 "Выражения " (ссылка не работает web.archive.org )

Теперь я немного запутался.Не означает ли это, что i = i++ - это определенное поведение?На этот раз я посмотрел на другой черновик, C99:

Выражение - это последовательность операторов и операндов, которая задает вычисление значения, или обозначает объект или функцию, или которая генерирует побочные эффекты,или который выполняет их комбинацию.
Источник: ИСО / МЭК 9899: 1999, раздел 6.5 §1 "Выражения"

В этом предложении отсутствует этот текст!

Вопросы

  1. Я что-то не так понял?
  2. Ответы устарели?
  3. Я смотрел неправильный черновик?

Ответы [ 2 ]

0 голосов
/ 26 ноября 2018

Полная история.В 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.

0 голосов
/ 25 ноября 2018

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

Этот отрывок впервые появился в C11 , поэтому нет изменений по сравнению с этой версией C17.

...