Bod na trase

Aktuální verze stránky ještě nebyla zkontrolována zkušenými přispěvateli a může se výrazně lišit od verze recenzované 9. listopadu 2016; kontroly vyžadují 7 úprav .

Sekvenční bod - v programování jakýkoli bod v programu  , u kterého je zaručeno, že se již objevily všechny vedlejší účinky předchozích výpočtů a vedlejší účinky následujících výpočtů stále chybí.

Když se mluví o jazycích C a C++ , často se zmiňují sekvenční body . V těchto jazycích je možné napsat výraz, jehož pořadí vyhodnocení podvýrazů není definováno normami a ovlivňuje výsledek. Přidání jednoho nebo více bodů sekvence umožňuje v některých případech zaručit pořadí hodnocení.

Stojí za zmínku, že přístup k zefektivnění procesu vyhodnocování výrazů na základě sekvenčních bodů zpočátku docela dobře vyhovoval potřebám jazyka C, ale nebyl adekvátní pro jazyk C++, ve kterém byla množina operátorů vracejících výsledky lvalue výrazně rozšířena. A s příchodem potřeby jazykové podpory pro multithreading v C a C++ muselo být řazení založené na sekvenčních bodech zcela opuštěno. Moderní specifikace jazyků C a C++ popisují uspořádání procesu vyhodnocování výrazů prostřednictvím vztahů, uspořádané před ( seřazeno před ) a seřazené po ( seřazeno po ). Počínaje standardem C++11 již pojem sekvenčního bodu v jazyce C++ neexistuje . V C přežil pojem sekvenční bod dodnes, ale od standardu C11 ne jako základní pojem, ale pouze jako kombinace relací uspořádaných před a uspořádaných po .

Standard C++11 , stejně jako následné standardy C++14 a C++17 , zavedly operátorům jazyka C++ na základě nového modelu velké množství dalších uspořádání, což vedlo k tomu, že mnoho výrazů, jejichž chování byl nedefinovaný v C ++98 , dostal dobře definované chování v moderním C++. Dnes přísnost objednávání procesu hodnocení výrazů v jazyce C++ výrazně převyšuje v jazyce C.

Příklady nejednoznačnosti v C a C++

Pokud existují nejasnosti, jazykové standardy C a C++:

  1. označte několik přijatelných chování z možných (viz nespecifikované chování );
  2. označují jediné přijatelné chování mezi možnými popř
  3. explicitně označte, že chování není definováno (viz nedefinované chování ).

Příklad 1: Nespecifikované chování.

g () + f ()

Operátor " " není bod sekvence, takže není známo, která z funkcí bude volána jako první: nebo . Chování závisí na implementaci kompilátoru . +f()g()

Příklad 2: Jediné přijatelné chování.

f (), g ()

Operátor „ “ je sekvenční bod, takže pořadí vyhodnocení je zaručeno standardem a je předem známé (zleva doprava): ,

  • levý operand je vyhodnocen jako první: funkce je volána ;f()
  • pak ten pravý: funkce se nazývá .g()

Příklad 3: Nedefinované chování.

i = i ++

Z hlediska jazyka C obsahuje zadaný výraz více modifikací proměnné , které nejsou vzájemně řazeny. Chování tohoto výrazu není definováno. (Přitom z pohledu moderního jazyka C++, který mnohem přísněji zefektivňuje proces hodnocení operátoru přiřazení, je chování tohoto výrazu zcela definováno.) i

Sekvenční body v C a C++

V původních jazykových standardech C a C++ byly definovány následující sekvenční body:

  • sekvenční body pro operátory " && ", " || “ a „ “ . U těchto operátorů je zaručeno, že budou vyhodnoceny zleva doprava, pokud nebudou přetíženy. Příklad. Ve výrazu " " je nejprve vyhodnocen levý operand (" "); výsledek je přetypován na typ a porovnán s ; pokud je rovno , vyhodnotí se pravý operand (" "), jinak ;*p++ != 0 && *q++ != 0*p++ != 0booltruetrue*q++ != 0false
  • sekvenční bod pro ternární operátor " ?: ". 1. operand je vyhodnocen jako první; pak se nachází následující bod; 2. operand je vyhodnocen pouze tehdy, je-li 1. operand roven ; 3. operand je vyhodnocen pouze v případě, že je 1. operand . Příklad. Ve výrazu „ “ se jako první provede 1. operand („ “; proměnná je zvýšena o ); výsledek výpočtu se přenese do typu a porovná se s ; je-li rovno , provede se 2. operand („ “), jinak 3. („ 0 “);truefalsea == (*p++) ? (*p++) : 0*p++p1booltruetrue(*p++)
  • sekvenční body ve výrazech:
    • místo symbolu " " ve výrazech, které jsou samostatnými instrukcemi. Například ve výrazu " " je místo " " vložen bod sekvence ;;a = b;;
    • na konci výrazu napsaného za klíčovým slovem ; přesněji v okamžiku, kdy bude návratová hodnota zkopírována do kontextu volající funkce. Tento bod sekvence je explicitně deklarován pouze ve standardu C++;return
    • na konci výrazů zapsaných v závorkách za klíčovými slovy , , (včetně konstrukcí );ifswitchwhilewhiledo-while
    • na koncích každého ze tří výrazů pro smyčku ;for
  • před voláním funkce. Pořadí, ve kterém jsou argumenty funkce vyhodnocovány, není definováno. Sekvenční bod zajišťuje, že všechny argumenty jsou vyhodnoceny před voláním funkce. Příklad. Zvažte výraz „ “. Nejprve se vytvoří dočasná proměnná s hodnotou rovnou hodnotě proměnné ; pak je na proměnnou (nikoli dočasná) zavolán operátor "postfix ++" ); nakonec je funkce volána  s dočasnou proměnnou jako argumentem. Výše uvedené platí pro proměnné a funkce . Zároveň kvůli chybějícímu bodu sekvence pro operátor „+“ není definováno pořadí volání funkcí , a . Proto pořadí volání operátorů „postfix ++“ pro proměnné a není definováno . To znamená, že když je funkce spuštěna, není známo, zda byly pro proměnné a operátory "postfix ++" volány . Příklad. Zvažte výraz „ “. Čárka mezi argumenty funkce není operátorem „čárka“ a nezaručuje pořadí, ve kterém jsou hodnoty argumentů vyhodnocovány. Pořadí, ve kterém jsou vyhodnocovány hodnoty argumentů funkcí, není standardizované a závisí na implementaci kompilátoru;f( i++ ) + g( j++ ) + h( k++ )iif()jkg()h()f()g()h()ijkf()jkf( a, b, c )
  • v deklaraci s inicializací v okamžiku dokončení výpočtu inicializační hodnoty. Příklad. Zvažte výraz „ “. Sekvenční bod je vložen po vyhodnocení výrazu " ";int a = ( 1 + i++ );( 1 + i++ )
  • před voláním přetíženého operátora v C++. Sekvenční bod zajišťuje, že hodnoty argumentů operátoru (stejně jako běžná funkce) jsou vyhodnoceny před jeho voláním.

Viz také

Odkazy

Poznámky