- Точка следования
-
Точка следования (англ. Sequence point) — в программировании любая точка программы, в которой гарантируется, что все побочные эффекты предыдущих вычислений уже проявились, а побочные эффекты последующих еще отсутствуют.
Их часто упоминают, говоря о языках C и C++, поскольку в этих языках особенно просто записать выражение, значение которого может зависеть от неопределённого порядка проявления побочных эффектов. Добавление одной или нескольких точек следования задает порядок более жестко и является одним из методов достижения устойчивого (то есть корректного) результата.
Содержание
Примеры неоднозначности
Рассмотрим две функции
f()иg(). По стандарту языка C и C++ оператор сложения+не является точкой следования, поэтому в выраженииg()+f()возможно, что любая из функций может быть вычислена первой. Оператор,является точкой следования, и потому для выраженияf(),g()функции будут вычислены в том порядке, в котором записаны: сначалаf(), затемg(). Тип и значение всего выражения определяются в данном случае функциейg(), значение жеf()будет утеряно.Точки следования необходимы в ситуации, когда одна и та же переменная изменяется в выражении более одного раза. Часто в качестве примера приводят выражение
i=i++, в котором происходит присваивание переменнойiи её же инкремент. Какое значение примет i? Стандарт языка должен либо указать одно из возможных поведений программы как единственно допустимое, либо указать диапазон допустимых поведений (см. неуточняемое поведение), либо указать, что поведение программы в данном случае совершенно не определено (см. неопределённое поведение). В языках C и C++ вычисление выраженияi=i++приводит к неопределённому поведению, поскольку это выражение не содержит внутри себя ни одной точки следования.Точки следования в языках C и C++
В C и C++ определены следующие точки следования:
- Между вычислением левого и правого операндов в операторах && (логическом И), || (логическом ИЛИ) и операторах-запятых. Например, в выражении
*p++ != 0 && *q++ != 0все побочные эффекты левого операнда*p++ != 0проявятся до начала каких либо действий в правом. - Между вычислением первого и второго или третьего операндов в операторе условия. В строке
a = (*p++) ? (*p++) : 0точка находится после первого операнда*p++, при выполнении второгоpуже увеличена на 1. - В конце всего выражения. Эта категория включает в себя инструкции-выражения (
a=b;), выражения в инструкциях return, управляющие выражения в круглых скобках инструкций ветвленияifилиswitchи цикловwhileилиdo-whileи все три выражения в круглых скобках циклаfor. - Перед входом в вызываемую функцию. Порядок, в котором вычисляются аргументы не определен, но эта точка следования гарантирует, что все ее побочные эффекты проявятся на момент входа в функцию. В выражении
f(i++) + g(j++) + h(k++)каждая из трёх переменных:i,jиk, принимает новое значение перед входом вf,gиhсоответственно. Однако, порядок вызова функцийf(),g(),h()неопределён, следовательно неопределён и порядок инкрементаi,j,k. Значенияjиkв теле функцииfоказываются неопределенными. Следует заметить, вызов функции нескольких аргументовf(a,b,c)не является случаем применения оператора-запятой и не определяет порядок вычисления значений аргументов. - При возврате из функции, на момент когда возвращаемое значение будет скопировано в вызывающий контекст.(Явно описана только в стандарте С++, в отличие от С.)
- В объявлении с инициализацией на момент завершения вычисления инициализирующего значения, например, на момент завершения вычисления
(1+i++)вint a = (1+i++);.
(В C++ перегруженные операторы выступают в роли функций, поэтому точкой следования является вызов перегруженного оператора)
См. также
- Приоритет операций
Ссылки
Категория:- Программирование
- Между вычислением левого и правого операндов в операторах && (логическом И), || (логическом ИЛИ) и операторах-запятых. Например, в выражении
Wikimedia Foundation. 2010.