последовательность точек в с - PullRequest
27 голосов
/ 26 августа 2010

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

Что это значит?Может кто-нибудь объяснить это простыми словами?

Ответы [ 4 ]

39 голосов
/ 26 августа 2010

Когда возникает точка последовательности, это в основном означает, что вам гарантировано, что все предыдущие операции завершены.

Изменение переменной дважды без промежуточной точки последовательности является одним из примеров неопределенного поведения.

Например, i = i++; не определено, потому что между двумя изменениями нет i.

Обратите внимание, что не только изменение переменной дважды может вызвать проблему. На самом деле это изменение связано с любым другим использованием. Стандарт использует термин «вычисление значения и побочный эффект» при обсуждении последовательности вещей. Например, в выражении a = i + i++ i (вычисление значения) и i++ (побочный эффект) могут выполняться в произвольном порядке.

В Википедии есть список точек последовательности в стандартах C и C ++, хотя окончательный список всегда следует брать из стандарта ISO. Из добавления С11 в приложении С (перефразировано):


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

  • Между оценками обозначения функции и фактическими аргументами в вызове функции и фактическим вызовом;
  • Между оценками первого и второго операндов операторов &&, || и ,;
  • Между оценками первого операнда условного оператора ?: и любым из второго и третьего операндов оценивается;
  • Конец полного декларатора;
  • Между оценкой полного выражения и следующим полным выражением, которое будет оценено. Ниже приведены полные выражения:
    • инициализатор;
    • выражение в выражении выражения;
    • управляющее выражение оператора выбора (if или switch);
    • управляющее выражение оператора while или do;
    • каждое из выражений оператора for;
    • выражение в операторе возврата.
  • Непосредственно перед возвратом библиотечной функции;
  • После действий, связанных с каждым отформатированным спецификатором преобразования функций ввода / вывода;
  • Непосредственно перед и сразу после каждого вызова функции сравнения, а также между любым вызовом функции сравнения и любым движением объектов, переданных в качестве аргументов для этого вызова.
10 голосов
/ 26 августа 2010

Важно отметить, что точки последовательности являются не глобальными, а должны рассматриваться как набор локальных ограничений. Например, в заявлении

a = f1(x++) + f2(y++);

Существует точка последовательности между вычислением x ++ и вызовом f1, и другая точка последовательности между оценкой y ++ и вызовом f2. Однако нет никакой гарантии относительно того, будет ли x увеличен до или после вызова f2, и не будет ли y увеличен до или после вызова x. Если f1 меняет y или f2 меняет x, результаты будут неопределенными (было бы законно для сгенерированного кода компилятора, например, прочитать x и y, увеличить x, вызвать f1, проверить y относительно ранее прочитанного значения и - если все изменилось - яростно отыскиваю и уничтожаю все видео и товары Барни; я не думаю, что какие-то реальные компиляторы генерируют код, который бы на самом деле это делал, увы, но это было бы разрешено по стандарту).

3 голосов
/ 26 августа 2010

Расширение ответа Паксдиабло на примере.

Предположим, что оператор

x = i++ * ++j;

Существует три побочных эффекта: присвоение результата i * (j+1) для x, добавление 1 к i и добавление 1 к j.Порядок применения побочных эффектов не определен;Каждый из i и j может быть увеличен сразу после оценки, или они не могут быть увеличены до тех пор, пока оба не будут оценены, но до того, как x был назначен, или они не могут быть увеличены до тех пор, пока x не был назначен.

Точка последовательности - это точка, в которой были применены все побочные эффекты (все x, i и j обновлены), независимо от порядка их применения.

1 голос
/ 26 августа 2010

Это означает, что компилятор может выполнять неожиданные оптимизации, трюки и магию, но должен достичь четко определенного состояния в этих так называемых точках последовательности.

...