2012-01-30 6 views
4

Я читал через K & R и я натолкнулся на этот пример об неопределенности в поведении при оценке выражения типа a[i]=i++; C99 спецификации в $ 6.5.2 говорит, чтоПоследовательность точек и порядок оценки

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

Приведенный выше пример из K & R имеет хорошее значение в первом утверждении. Пожалуйста, объясните, как это происходит на втором.

Знает ли стандарт что-либо о порядке оценки подвыражений в случае задействованных точек последовательности. Например. a[i++] || b[i++]. Я знаю, что они оцениваются слева направо, но как это можно получить из приведенного выше утверждения или явно указано в стандарте где-то?

+0

Возможный дубликат [Любая хорошая причина, по которой оператор присваивания не является точкой последовательности?] (Http://stackoverflow.com/questions/4362501/any-good-reason-why-assignment-operator-isnt-a- точка последовательности) – Suma

+1

Возможный дубликат [Неопределенное поведение и точки последовательности] (http://stackoverflow.com/questions/4176328/undefined-behavior-and-sequence-points) – Lundin

+0

@Lundin: Это C++. –

ответ

4

Означает ли стандарт что-либо о порядке оценки подвыражений в случае точек последовательности?

Порядок оценки хорошо определен в случае условных операторов &&, а также ||, и именно по этой причине работы с коротким замыканием.

Это явно указано стандартом c99.

Ссылка: C99 Стандартный

приложение J: J.1 Не выбрано поведение

1 Следующие неопределенные:
.....

Порядок какие подвыражения оцениваются, и порядок, в котором происходят побочные эффекты , за исключением случаев, указанных для функции-вызова(), & &, ||,?: И запятая Операторы (6.5).
.....

Далее в,
6.5.14 логический оператор ИЛИ

4) В отличие от побитового | оператора, || оператор гарантирует оценку слева направо; после оценки первого операнда есть точка последовательности. Если первый операнд сравнивается не равным 0, второй операнд не оценивается.

Как и для логического И:

6.5.13 логический оператор

В отличие от побитового двоичного & оператора, то оператор & & гарантии влево-вправо оценки; , если второй операнд оценивается, имеется точка последовательности между оценками первого и второго операндов. Если первый операнд сравнивается с 0, второй операнд не оценивается.

+1

Спасибо, но можете ли вы дать некоторое объяснение по поводу первого вопроса, который я задал о [i] = i ++ ; – Bazooka

+0

Оператор присваивания Parminder не является точкой последовательности в C. Примечание: C++ 11 представляет концепцию секвенирования до/после, а [i] = i ++ [хорошо определен в C++ 11] (http: // www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2239.html). См. Также http://stackoverflow.com/questions/4362501/any-good-reason-why-assignment-operator-isnt-a-sequence-point – Suma

+0

УДИВИТЕЛЬНЫЙ ОТВЕТ! Это помогло мне с 'a || b ++ && c' знать, всегда ли оценивается 'b ++'. Это не так, но более высокий приоритет оператора && - приведет к тому, что многие люди потребуют иного. –

0

Для первой части вопроса:

Предложение относится к объектам изменяется выражением, т.е. ia[i]). Таким образом, предварительное значение i должно использоваться исключительно для определения «нового» значения для i.

Но выражение «использует» его также для определения элемента массива, на который нужно записать.

Фон заключается в том, что в противном случае было бы непонятно, означает ли i значение i до или после приращения.

+0

Спасибо, но у меня есть еще одно сомнение относительно этого. Выражение типа '++ i == i' кажется на первый взгляд двусмысленным. Но он не пытается «изменить» что-либо, кроме i. Так это тоже неопределенное поведение? – Bazooka

+0

Я не пытаюсь изменить lvalue. Все, что я пытаюсь сказать, заключается в том, что при оценке справа налево я меняю «i» только один раз, и когда я получаю доступ к «i» во второй раз, я делаю это, чтобы изменить значение «i». Это подтверждает второе утверждение, которое я предполагаю. Так в чем проблема ? Является ли это законным выражением с определенным поведением? – Bazooka

+0

Не происходит повторного присваивания, только операция приращения. Это '==' not '=', на всякий случай, если вы пропустили. – Bazooka