WikiSort.ru - Не сортированное

ПОИСК ПО САЙТУ | о проекте

Точка следования (англ. sequence point) — в программировании любая точка программы, в которой гарантируется, что все побочные эффекты предыдущих вычислений уже проявились, а побочные эффекты последующих ещё отсутствуют.

Точки следования часто упоминают, когда речь идёт о языках C и C++. В этих языках можно записать выражение, порядок вычисления подвыражений которого не определён стандартами и влияет на результат. Добавление одной или нескольких точек следования позволяет гарантировать порядок вычисления в некоторых случаях.

Примеры неоднозначности в языках C и C++

При наличии неоднозначностей стандарты языков C и C++:

  1. указывают несколько допустимых поведений из числа возможных (см. неуточняемое поведение);
  2. указывают единственно допустимое поведение из числа возможных либо
  3. явно указывают, что поведение не определено (см. неопределённое поведение).

Пример 1. Неуточняемое поведение.

g() + f()

Оператор «+ » не является точкой следования, поэтому неизвестно, какая из функций будет вызвана первой: f() или g() . Поведение зависит от реализации компилятора.

Пример 2. Единственно допустимое поведение.

f(), g()

Оператор «, » является точкой следования, поэтому порядок вычисления гарантируется стандартом и известен заранее (слева направо):

  • сначала вычисляется левый операнд: вызывается функция f() ;
  • затем — правый: вызывается функция g() .

Пример 3. Неопределённое поведение.

i = i++

Указанное выражение не содержит ни одной точки следования, поэтому компилятор не может определить порядок вычисления операторов, соответствующий стандартам. Поведение зависит от реализации компилятора.

Точки следования в языках C и C++

В стандартах языков C и C++ определены следующие точки следования:

  • точки следования для операторов «&&», «||» и «,». Эти операторы гарантированно вычисляются слева направо, если не перегружены. Пример. В выражении «*p++ != 0 && *q++ != 0 » сначала вычисляется левый операнд («*p++ != 0 »); результат приводится к типу bool и сравнивается с true ; если равен true , вычисляется правый операнд («*q++ != 0 »), иначе возвращается false ;
  • точка следования для тернарного оператора «?:». 1-й операнд вычисляется первым; затем располагается точка следования; 2-й операнд вычисляется только, если 1-й операнд равен true ; 3-й операнд вычисляется только, если 1-й операнд равен false . Пример. В выражении «a = (*p++) ? (*p++) : 0 » сначала выполняется 1-й операнд («*p++ »; переменная p увеличивается на 1 ); результат вычисления приводится к типу bool и сравнивается с true ; если равен true , выполняется 2-й операнд («(*p++) »), иначе — 3-й («0»);
  • точки следования в выражениях:
    • на месте символа «; » в выражениях, являющихся отдельными инструкциями. Например, в выражении «a = b; » точка следования вставляется вместо «; »;
    • в конце выражения, записанного после ключевого слова return ; а точнее, на момент, когда возвращаемое значение будет скопировано в контекст вызывающей функции. Эта точка следования явно описана только в стандарте С++;
    • в конце выражений, записанных в круглых скобках после ключевых слов if , switch , while (включая while в конструкции do-while);
    • в концах каждого из трёх выражений для цикла for ;
  • перед вызовом функции. Порядок вычисления аргументов функции не определён. Точка следования гарантирует, что все аргументы будут вычислены до вызова функции. Пример. Рассмотрим выражение «f( i++ ) + g( j++ ) + h( k++ ) ». Сначала создаётся временная переменная со значением, равным значению переменной i ; затем для переменной i (не для временной) вызывается оператор «постфиксный ++»; наконец, вызывается функция f()  с временной переменной в качестве аргумента. Сказанное справедливо для переменных j , k и функций g() , h() соответственно. При этом из-за отсутствия точки следования у оператора «+» порядок вызова функций f() , g() и h() не определён. Следовательно не определён и порядок вызова операторов «постфиксный ++» для переменных i , j и k . То есть при выполнении функции f() неизвестно, были ли вызваны операторы «постфиксный ++» для переменных j и k . Пример. Рассмотрим выражение «f( a, b, c ) ». Запятая между аргументами функции не является оператором «запятая» и не гарантирует порядок вычисления значений аргументов. Порядок вычисления значений аргументов функции не стандартизован и зависит от реализации компилятора;
  • в объявлении с инициализацией на момент завершения вычисления инициализирующего значения. Пример. Рассмотрим выражение «int a = ( 1 + i++ ); ». Точка следования вставляется после вычисления выражения «( 1 + i++ ) »;
  • перед вызовом перегруженного оператора в языке C++. Точка следования гарантирует вычисление значений аргументов оператора (как и обычной функции) до его вызова.

См. также

Ссылки

Примечания

    Данная страница на сайте WikiSort.ru содержит текст со страницы сайта "Википедия".

    Если Вы хотите её отредактировать, то можете сделать это на странице редактирования в Википедии.

    Если сделанные Вами правки не будут кем-нибудь удалены, то через несколько дней они появятся на сайте WikiSort.ru .




    Текст в блоке "Читать" взят с сайта "Википедия" и доступен по лицензии Creative Commons Attribution-ShareAlike; в отдельных случаях могут действовать дополнительные условия.

    Другой контент может иметь иную лицензию. Перед использованием материалов сайта WikiSort.ru внимательно изучите правила лицензирования конкретных элементов наполнения сайта.

    2019-2024
    WikiSort.ru - проект по пересортировке и дополнению контента Википедии