Ú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:

  1. jelöljön meg több elfogadható viselkedést a lehetségesek közül (lásd: nem meghatározott viselkedés );
  2. jelölje meg az egyetlen elfogadható magatartást a lehetséges ill
  3. 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