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++:
- označte několik přijatelných chování z možných (viz nespecifikované chování );
- označují jediné přijatelné chování mezi možnými popř
- 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