Punct de drum
Versiunea actuală a paginii nu a fost încă examinată de colaboratori experimentați și poate diferi semnificativ de
versiunea revizuită pe 9 noiembrie 2016; verificările necesită
7 modificări .
Punct de secvență - în programare , orice punct din program în care se garantează că au apărut deja toate efectele secundare ale calculelor anterioare, iar efectele secundare ale celor ulterioare sunt încă absente.
Punctele de secvență sunt adesea menționate atunci când vorbim despre limbajele C și C++ . În aceste limbi, este posibil să scrieți o expresie, a cărei ordine de evaluare a subexpresiilor nu este definită de standarde și afectează rezultatul. Adăugarea unuia sau mai multor puncte de secvență vă permite să garantați ordinea evaluării în unele cazuri.
Este de remarcat faptul că abordarea de eficientizare a procesului de evaluare a expresiilor bazate pe puncte de secvență a satisfăcut inițial nevoile limbajului C destul de bine, dar nu a fost adecvată pentru limbajul C++, în care setul de operatori care returnau rezultate lvalue a fost extins semnificativ. Și odată cu apariția necesității suportului de limbaj pentru multithreading în C și C ++, ordonarea bazată pe puncte de secvență a trebuit să fie complet abandonată. Specificațiile limbajului C și C++ modern descriu ordonarea procesului de evaluare a expresiilor prin relații, ordonate înainte ( secvenționat înainte ) și ordonat după ( secvenționat după ). Începând cu standardul C++11 , noțiunea de punct de secvență nu mai există în limbajul C++ . În C, noțiunea de punct de secvență a supraviețuit până astăzi, dar de la standardul C11 , nu ca un concept fundamental, ci doar ca o combinație de relații ordonate înainte și ordonate după .
Standardul C++11 , precum și standardele ulterioare C++14 și C++17 , au introdus un număr mare de ordonări suplimentare operatorilor limbajului C++ bazate pe noul model, ceea ce a dus la faptul că multe expresii al căror comportament a fost nedefinit în C++98 , a avut un comportament bine definit în C++ modern. Astăzi, strictețea ordonării procesului de evaluare a expresiilor în limbajul C++ o depășește semnificativ pe cea din limbajul C.
Exemple de ambiguitate în C și C++
Când există ambiguități, standardele limbajului C și C++:
- indicați mai multe comportamente acceptabile dintre cele posibile (vezi comportament nespecificat );
- indica singurul comportament acceptabil dintre posibili sau
- indicați în mod explicit că comportamentul este nedefinit (vezi comportament nedefinit ).
Exemplul 1: Comportament nespecificat.
g () + f ()
Operatorul „ ” nu este un punct de secvență, deci nu se știe care dintre funcții va fi numită prima: sau . Comportamentul depinde de implementarea compilatorului .
+f()g()
Exemplul 2: Singurul comportament acceptabil.
f (), g ()
Operatorul „ ” este un punct de secvență, astfel încât ordinea evaluării este garantată de standard și cunoscută în prealabil (de la stânga la dreapta):
,
- se evaluează mai întâi operandul din stânga: funcţia se numeşte ;f()
- apoi cea potrivită: funcția se numește .g()
Exemplul 3: Comportament nedefinit.
i = i ++
Din punctul de vedere al limbajului C, expresia specificată conține multiple modificări ale variabilei , neordonate una față de cealaltă. Comportamentul acestei expresii este nedefinit. (Totodată, din punctul de vedere al limbajului modern C++, care eficientizează mult mai strict procesul de evaluare a operatorului de atribuire, comportamentul acestei expresii este complet definit.)
i
Secvență puncte în C și C++
Următoarele puncte de secvență au fost definite în standardele originale ale limbajului C și C++:
- puncte de secvență pentru operatorii " && ", " || ” și “ , ”. Se garantează că acești operatori vor fi evaluați de la stânga la dreapta, dacă nu sunt supraîncărcați. Exemplu. În expresia " ", operandul din stânga (" ") este evaluat mai întâi; rezultatul este turnat la tip și comparat cu ; dacă este egal cu , operandul drept (" ") este evaluat, în caz contrar ;*p++ != 0 && *q++ != 0*p++ != 0booltruetrue*q++ != 0false
- punctul de secvență pentru operatorul ternar „ ?: ”. primul operand este evaluat mai întâi; atunci se localizează următorul punct; Al 2-lea operand este evaluat numai dacă primul operand este egal cu ; Al treilea operand este evaluat numai dacă primul operand este . Exemplu. În expresia “ ”, primul operand este executat mai întâi (“ ”; variabila este incrementată cu ); rezultatul calculului este turnat la tip și comparat cu ; dacă este egal , al 2-lea operand (“ ”) este executat, în caz contrar al 3-lea (“ 0 ”);truefalsea == (*p++) ? (*p++) : 0*p++p1booltruetrue(*p++)
- puncte de succesiune în expresii:
- în locul simbolului „ ” în expresiile care sunt instrucțiuni separate. De exemplu, în expresia " ", punctul de secvență este inserat în loc de " ";;a = b;;
- la sfârşitul unei expresii scrise după cuvântul cheie ; mai precis, în momentul în care valoarea returnată va fi copiată în contextul funcției de apelare. Acest punct de secvență este declarat doar explicit în standardul C++;return
- la sfârşitul expresiilor scrise între paranteze după cuvintele cheie , , (inclusiv în construcţii );ifswitchwhilewhiledo-while
- la capetele fiecăreia dintre cele trei expresii pentru buclă ;for
- înainte de a apela funcția. Ordinea în care argumentele funcției sunt evaluate nu este definită. Punctul de secvență asigură că toate argumentele sunt evaluate înainte ca funcția să fie apelată. Exemplu. Luați în considerare expresia " ". În primul rând, o variabilă temporară este creată cu o valoare egală cu valoarea variabilei ; apoi operatorul „postfix ++” este apelat pe variabilă (nu temporar); în cele din urmă, funcția este apelată cu variabila temporară ca argument. Cele de mai sus sunt valabile pentru variabile și , respectiv , funcții . În același timp, din cauza lipsei unui punct de secvență pentru operatorul „+”, ordinea de apelare a funcțiilor , și nu este definită. Prin urmare, ordinea de apelare a operatorilor „postfix ++” pentru variabile și nu este definită . Adică, atunci când funcția este executată, nu se știe dacă operatorii „postfix ++” au fost apelați pentru variabile și . Exemplu. Luați în considerare expresia " ". O virgulă între argumentele funcției nu este un operator „virgulă” și nu garantează ordinea în care sunt evaluate valorile argumentelor. Ordinea în care sunt evaluate valorile argumentelor funcției nu este standardizată și depinde de implementarea compilatorului;f( i++ ) + g( j++ ) + h( k++ )iif()jkg()h()f()g()h()ijkf()jkf( a, b, c )
- într-o declaraţie cu iniţializare la momentul finalizării calculului valorii de iniţializare. Exemplu. Luați în considerare expresia " ". Punctul secvenței este inserat după ce expresia „ ” a fost evaluată;int a = ( 1 + i++ );( 1 + i++ )
- înainte de a apela un operator supraîncărcat în C++. Punctul de secvență asigură că valorile argumentelor unui operator (la fel ca o funcție obișnuită) sunt evaluate înainte de a fi apelat.
Vezi și
Link -uri
Note