A sequence point in imperative programming defines any point in a computer program's execution at which it is guaranteed that all side effects of previous evaluations will have been performed, and no side effects from subsequent evaluations have yet been performed.
What does this mean? Can somebody please explain it in simple words?
Когда возникает точка последовательности, это в основном означает, что вам гарантировано завершение всех предыдущих операций.
Двойное изменение переменной без промежуточной точки следования — один из примеров неопределенного поведения.
Например, i = i++;
не определено, поскольку между двумя изменениями на i
нет точки следования.
Обратите внимание, что не только изменение переменной дважды может вызвать проблему. На самом деле это изменение, связанное с любым другим использованием. В стандарте используются термины «вычисление значения и побочный эффект» при обсуждении последовательности действий.Например, в выражении
a = i + i++
i
(вычисление значения) иi++
(побочный эффект) могут выполняться в произвольном порядке.
В Википедии есть список точек последовательности в стандартах C и C++, хотя окончательный список всегда следует брать из стандарта ISO. Из приложения C C11 (перефразировано):
Ниже приведены точки последовательности, описанные в стандарте:
&&
, ||
и ,
;?:
оператор и вычисляемый второй и третий операнды;if
или switch
);while
или do;for
;Важно отметить, что точки следования не являются глобальными, а скорее должны рассматриваться как набор локальных ограничений. Например, в операторе
a = f1(x++) + f2(y++);
есть точка последовательности между оценкой x++ и вызовом f1, а другая точка последовательности между оценкой y++ и вызовом f2. Однако нет никакой гарантии относительно того, будет ли увеличиваться x до или после вызова f2, а также будет ли увеличиваться y до или после вызова x. Если f1 изменяет y или f2 изменяет x, результаты будут неопределенными (для сгенерированного кода компилятора было бы допустимо, например, считать x и y, увеличить x, вызвать f1, проверить y на соответствие ранее прочитанному значению и -- если он изменился — неистовствуйте, разыскивая и уничтожая все видео и товары Барни; я не думаю, что какие-либо настоящие компиляторы генерируют код, который действительно мог бы это сделать, увы, но это было бы разрешено стандартом).
Расширение ответа paxdiablo на примере.
Допустим оператор
x = i++ * ++j;
Есть три побочных эффекта: присваивание результата i * (j+1)
x, прибавление 1 к i и прибавление 1 к j. Порядок применения побочных эффектов не указан; Каждый из i и j может быть увеличен сразу же после оценки, или они не могут быть увеличены до тех пор, пока оба не будут оценены, но до того, как x будет присвоено, или они не могут быть увеличены до тех пор, пока не будет присвоено значение x.
Точка следования — это точка, в которой были применены все побочные эффекты (все x, i и j были обновлены), независимо от порядка их применения.
Это означает, что компилятор может делать забавные оптимизации, трюки и магию, но должен достичь четко определенного состояния в этих так называемых точках последовательности.