Точки последовательности в c

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

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

Ответ 1

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

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

Например, i = i++; - undefined, потому что между этими двумя изменениями не существует точки последовательности i.

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


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

  • Вызов функции после оценки аргументов (6.5.2.2).
  • Конец первого операнда следующих операторов: логический AND && (6.5.13); логический ИЛИ || (6.5.14); условный? (6.5.15); запятая, (6.5.17).
  • Конец полного декларатора: деклараторы (6.7.5);
  • Конец полного выражения: инициализатор (6.7.8); выражение в выражении утверждение (6.8.3); управляющее выражение оператора выбора (если или переключатель) (6.8.4); управляющее выражение while или do (6.8.5); каждый из выражения оператора for (6.8.5.3); выражение в операторе return (6.8.6.4).
  • Непосредственно перед возвратом функции библиотеки (7.1.4).
  • После действий, связанных с каждым преобразованием форматированных входных/выходных функций спецификатор (7.19.6, 7.24.2).
  • Непосредственно перед и сразу после каждого вызова функции сравнения и также между любым вызовом функции сравнения и любым перемещением объектов переданные в качестве аргументов для этого вызова (7.20.5).

С11 изменена формулировка. Похоже, что он разбил тернарный оператор и добавил несколько деталей:


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

  • Между оценками имени функции и фактическими аргументами в функции вызова и фактического вызова. (6.5.2.2).
  • Между оценками первого и второго операндов следующих операторов: логический И && (6.5.13); логический ИЛИ || (6.5.14); запятая, (6.5.17).
  • Между оценками первого операнда условного?: оператора и какой из второго и третьего операндов оценивается (6.5.15).
  • Конец полного декларатора: деклараторы (6.7.6);
  • Между оценкой полного выражения и следующего полного выражения, которое должно быть оценены. Ниже приведены полные выражения: инициализатор (6.7.9); выражение в выражение (6.8.3); управляющее выражение выражения выбора (если или переключатель) (6.8.4); управляющее выражение while или do statement (6.8.5); каждое из выражений оператора for (6.8.5.3); выражение в return (6.8.6.4).
  • Непосредственно перед возвратом функции библиотеки (7.1.4).
  • После действий, связанных с каждым преобразованием форматированных входных/выходных функций спецификатор (7.21.6, 7.28.2).
  • Непосредственно перед и сразу после каждого вызова функции сравнения и также между любым вызовом функции сравнения и любым перемещением объектов переданные в качестве аргументов для этого вызова (7.22.5).

Ответ 2

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

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

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

Ответ 3

Развернувшись на paxdiablo, ответьте на пример.

Предположим, что утверждение

x = i++ * ++j;

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

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

Ответ 4

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