Неопределенное поведение и точка последовательности

Последние несколько дней я пытался узнать о неопределенном поведении. Несколько дней назад я нашел ссылку c-faq. Это очень помогает устранить многие недоразумения, но создает еще одну большую путаницу, когда я читаю вопрос # 3.8. После того, как я приложил много усилий, чтобы понять это утверждение (особенно второе предложение);

Стандарт гласит, что

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

Мне было лучше задать этот вопрос на SO, но ни один из ответов там не объяснял второй предложение этого заявления. Наконец, я получил объяснение по этому поводу. Прочитав его и часто задаваемые вопросы, я пришел к выводу, что;

1. последнее предложение

Кроме того, к предыдущему значению нужно обращаться только для определения значения, которое будет сохранено

было бы так;

Кроме того, к предыдущему значению объекта следует обращаться только для определения измененного / нового значения (того же объекта), которое должно быть хранится.

Как видно на примере

 int i = 1, j, a[5];    
 i = i + 1;
 j = i + 1;
 a[i] = i; 

в случае выражения i = i + 1 осуществляется доступ к предыдущему значению (которое здесь 1) i (в R.H.S) для определения значения i, которое будет сохранено. В то время как в случае j = i + 1 и a[i] = i доступное значение i является просто значением не предшествующим значением, так как no, где i изменяется в этих операторах.

2. В случае выражения a[i] = i++ или a[i++] = i, первое предложение вышеприведенного утверждения

Между предыдущей и следующей точкой последовательности сохраненное значение объекта должно быть изменено не более одного раза при оценке выражения.

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

Проблема начинается, когда я придумал выражение i = i++, о котором говорится в c-faq

На самом деле, другие обсуждаемые нами выражения также нарушают второе предложение.

Я думаю, что в этом выражении i (в R.H.S) осуществляется доступ для определения измененного значения i.
Как это выражение нарушает второй оператор?


person haccks    schedule 10.07.2013    source источник


Ответы (1)


Подумайте об этом таким образом:

a = i++;

эквивалентно:

a = i;
i++;

Доступ к значению i в приращении не имеет ничего общего с определением того, какое значение a будет сохранено в a. Итак, i = i++ содержит две модификации i (что запрещено первым предложением), но также, модификация i = для i не зависит от одного из обращений к i в i++.

Я думаю, что кто-то там был очень умным. Нет необходимости рассчитывать, насколько неопределенное поведение является неопределенным. Достаточно изменить значение дважды undefined.

person Art    schedule 11.07.2013
comment
Ну, если быть педантичным, не определено, сколько раз к нему обращаются, потому что все выражение не определено. - person Art; 12.07.2013