Útpont
Az oldal jelenlegi verzióját még nem ellenőrizték tapasztalt közreműködők, és jelentősen eltérhet a 2016. november 9-én felülvizsgált
verziótól ; az ellenőrzések 7 szerkesztést igényelnek .
Sorozatpont - a programozásban , a program bármely olyan pontja, ahol garantált, hogy a korábbi számítások összes mellékhatása már megjelent, és a későbbiek mellékhatásai továbbra is hiányoznak.
A szekvenciapontokat gyakran említik, amikor a C és C++ nyelvekről beszélünk . Ezeken a nyelveken lehet olyan kifejezést írni, amelynek részkifejezéseinek kiértékelési sorrendjét a szabványok nem határozzák meg, és az eredményt befolyásolja. Egy vagy több szekvenciapont hozzáadásával bizonyos esetekben garantálható a kiértékelés sorrendje.
Érdemes megjegyezni, hogy a kifejezések szekvenciapontokon alapuló kiértékelési folyamatának racionalizálásának megközelítése kezdetben elég jól megfelelt a C nyelv igényeinek, de nem volt megfelelő a C ++ nyelvhez, amelyben az lvvalue eredményeket visszaadó operátorkészlet jelentősen bővült. És miután megjelent a nyelvi támogatás igénye a többszálú C- és C++-ban, a szekvenciapontokon alapuló rendezést teljesen el kellett hagyni. A modern C és C++ nyelvi specifikációk a kifejezések relációkon keresztüli kiértékelésének folyamatát írják le, előtte ( sorrendben előtte ) és utána ( sorrendben utána ) rendezve. A C++11 szabványtól kezdve a sorozatpont fogalma már nem létezik a C++ nyelvben . C-ben a szekvenciapont fogalma a mai napig fennmaradt, de a C11 szabvány óta nem alapfogalomként, hanem csak az előtte és utána rendezett relációk kombinációjaként .
A C++11 szabvány , valamint az azt követő C++14 és C++17 szabványok számos további rendezést vezettek be a C++ nyelvi operátorokba az új modell alapján, ami ahhoz vezetett, hogy sok olyan kifejezés, amelynek viselkedése undefined volt a C ++98 -ban, jól definiált viselkedést kapott a modern C++-ban. Napjainkban a C++ nyelvű kifejezések kiértékelési folyamatának rendezésének szigorúsága jelentősen meghaladja a C nyelvét.
Példák a kétértelműségre C és C++ nyelven
Kétértelműség esetén a C és C++ nyelvi szabványok:
- jelöljön meg több elfogadható viselkedést a lehetségesek közül (lásd: nem meghatározott viselkedés );
- jelölje meg az egyetlen elfogadható magatartást a lehetséges ill
- kifejezetten jelzik, hogy a viselkedés nem definiált (lásd: undefined behavior ).
1. példa: Meghatározatlan viselkedés.
g () + f ()
A " " operátor nem szekvenciapont, így nem ismert, hogy melyik függvény hívódik meg először: vagy . A viselkedés a fordító megvalósításától függ .
+f()g()
2. példa: Az egyetlen elfogadható viselkedés.
f (), g ()
A „ ” operátor egy szekvenciapont, így a kiértékelés sorrendjét a szabvány garantálja és előre ismert (balról jobbra):
,
- először a bal oldali operandus kerül kiértékelésre: a függvény meghívása ;f()
- akkor a megfelelőt: a függvényt .g()
3. példa: Nem meghatározott viselkedés.
i = i ++
A C nyelv szempontjából a megadott kifejezés a változó többszörös , egymáshoz képest nem rendezett módosítását tartalmazza. Ennek a kifejezésnek a viselkedése nem definiált. (Ugyanakkor a hozzárendelési operátor értékelési folyamatát sokkal szigorúbban leegyszerűsítő modern C++ nyelv szempontjából ennek a kifejezésnek a viselkedése teljesen meghatározott.)
i
Sorozatpontok C-ben és C++-ban
A következő szekvenciapontokat határozták meg az eredeti C és C++ nyelvi szabványokban:
- szekvenciapontok az " && ", " || operátorokhoz ” és „ , ”. Ezek a kezelők garantáltan balról jobbra kerülnek kiértékelésre, hacsak nincsenek túlterhelve. Példa. A " " kifejezésben a bal oldali operandus (" ") kerül kiértékelésre először; az eredményt a típusra öntjük és összehasonlítjuk a -val ; ha egyenlő , akkor a jobb oldali operandus (" ") kerül kiértékelésre, ellenkező esetben ;*p++ != 0 && *q++ != 0*p++ != 0booltruetrue*q++ != 0false
- a " ?: " hármas operátor szekvenciapontja . Először az 1. operandus kerül kiértékelésre; akkor a következő pont található; A 2. operandus csak akkor kerül kiértékelésre, ha az 1. operandus egyenlő ; A 3. operandus csak akkor kerül kiértékelésre, ha az 1. operandus . Példa. A " " kifejezésben először az 1. operandus kerül végrehajtásra (" "; a változó értéke növekszik ); a számítás eredményét a típusra öntjük és összehasonlítjuk a -val ; ha egyenlő , a 2. operandus (“ ”) kerül végrehajtásra, ellenkező esetben a 3. (“ 0 ”);truefalsea == (*p++) ? (*p++) : 0*p++p1booltruetrue(*p++)
- szekvencia pontok a kifejezésekben:
- a " " szimbólum helyett olyan kifejezésekben, amelyek külön utasítások. Például a " " kifejezésben a sorozatpont kerül beillesztésre a " " helyett ;;a = b;;
- a kulcsszó után írt kifejezés végén ; pontosabban abban a pillanatban, amikor a visszatérési érték be lesz másolva a hívó függvény környezetébe. Ezt a szekvenciapontot csak a C++ szabvány írja le kifejezetten;return
- a , , kulcsszavak után zárójelben írt kifejezések végén ( szerkezetekben is );ifswitchwhilewhiledo-while
- a ciklus mindhárom kifejezésének végén ;for
- a függvény meghívása előtt. A függvényargumentumok kiértékelésének sorrendje nincs meghatározva. A szekvenciapont biztosítja, hogy minden argumentum ki legyen értékelve a függvény meghívása előtt. Példa. Vegye figyelembe a " " kifejezést . Először egy ideiglenes változót hozunk létre, amelynek értéke megegyezik a változó értékével ; akkor a "postfix ++" operátor meghívódik a változón (nem az ideiglenesen); végül a függvényt az ideiglenes változóval mint argumentumot hívjuk meg. A fentiek igazak a változókra és a függvényekre . Ugyanakkor a „+” operátor szekvenciapontjának hiánya miatt a , és függvények meghívásának sorrendje nincs meghatározva. Ezért a , és változók „postfix ++” operátorainak hívásának sorrendje nincs meghatározva . Ez azt jelenti, hogy a függvény végrehajtásakor nem tudni, hogy a "postfix ++" operátorok meghívásra kerültek-e az és a változókhoz . Példa. Vegye figyelembe a " " kifejezést . A függvény argumentumai közötti vessző nem "vessző" operátor, és nem garantálja az argumentumértékek kiértékelésének sorrendjét. A függvény argumentumértékeinek kiértékelési sorrendje nem szabványos, és a fordító megvalósításától függ;f( i++ ) + g( j++ ) + h( k++ )iif()jkg()h()f()g()h()ijkf()jkf( a, b, c )
- nyilatkozatban az inicializálással az inicializálási érték számításának befejezésekor. Példa. Vegye figyelembe a " " kifejezést . A sorozatpont a " " kifejezés kiértékelése után kerül beszúrásra ;int a = ( 1 + i++ );( 1 + i++ )
- mielőtt felhívna egy túlterhelt operátort C++ nyelven. A szekvenciapont biztosítja, hogy egy operátor argumentumainak értékei (akárcsak egy szabályos függvénynél) ki legyenek értékelve, mielőtt meghívnák.
Lásd még
Linkek
Jegyzetek