Waypoint

Den aktuella versionen av sidan har ännu inte granskats av erfarna bidragsgivare och kan skilja sig väsentligt från versionen som granskades den 9 november 2016; kontroller kräver 7 redigeringar .

Sekvenspunkt - i programmering , vilken  punkt som helst i programmet där det är garanterat att alla biverkningar från tidigare beräkningar redan har dykt upp, och biverkningarna av efterföljande är fortfarande frånvarande.

Sekvenspunkter nämns ofta när man talar om språken C och C++ . På dessa språk är det möjligt att skriva ett uttryck vars ordningsföljd för utvärdering av underuttryck inte definieras av standarderna och påverkar resultatet. Genom att lägga till en eller flera sekvenspunkter kan du garantera utvärderingsordningen i vissa fall.

Det är värt att notera att tillvägagångssättet för att effektivisera processen för att utvärdera uttryck baserat på sekvenspunkter till en början uppfyllde behoven för C-språket ganska bra, men var inte adekvat för C ++-språket, där den uppsättning operatorer som returnerade lvalue- resultat var kraftigt utökat. Och med tillkomsten av behovet av språkstöd för multithreading i C och C++, måste beställning baserad på sekvenspunkter helt överges. Moderna C- och C++-språkspecifikationer beskriver ordningen av processen för att utvärdera uttryck genom relationer, ordnade före ( sekvenserad före ) och ordnad efter ( sekvenserad efter ). Från och med C++11 -standarden existerar inte begreppet en sekvenspunkt längre i C++-språket . I C har föreställningen om en sekvenspunkt överlevt till denna dag, men sedan C11- standarden , inte som ett grundläggande begrepp, utan bara som en kombination av relationer ordnade före och ordnade efter .

C ++ 11-standarden , såväl som efterföljande C++14- och C++17-standarder , introducerade ett stort antal ytterligare beställningar till C++-språkoperatorerna baserade på den nya modellen, vilket ledde till att många uttryck vars beteende var odefinierad i C ++98 , fick ett väldefinierat beteende i modern C++. Idag överskrider strängheten i att beställa processen att utvärdera uttryck i C++-språket betydligt det i C-språket.

Exempel på tvetydighet i C och C++

När det finns oklarheter, språkstandarderna C och C++:

  1. ange flera acceptabla beteenden bland de möjliga (se ospecificerat beteende );
  2. ange det enda acceptabla beteendet bland de möjliga eller
  3. ange uttryckligen att beteendet är odefinierat (se odefinierat beteende ).

Exempel 1: Ospecificerat beteende.

g () + f ()

Operatorn " " är inte en sekvenspunkt, så det är inte känt vilken av funktionerna som kommer att anropas först: eller . Beteendet beror på implementeringen av kompilatorn . +f()g()

Exempel 2: Det enda acceptabla beteendet.

f (), g ()

Operatören " " är en sekvenspunkt, så utvärderingsordningen garanteras av standarden och är känd i förväg (från vänster till höger): ,

  • den vänstra operanden utvärderas först: funktionen kallas ;f()
  • sedan den högra: funktionen kallas .g()

Exempel 3: Odefinierat beteende.

i = i ++

Ur C-språkets synvinkel innehåller det angivna uttrycket flera modifieringar av variabeln , inte ordnade i förhållande till varandra. Beteendet för detta uttryck är odefinierat. (Samtidigt, ur det moderna C++-språkets synvinkel, som effektiviserar processen för utvärdering av uppdragsoperatören mycket striktare, är beteendet för detta uttryck helt definierat.) i

Sekvenspunkter i C och C++

Följande sekvenspunkter definierades i de ursprungliga språkstandarderna C och C++:

  • sekvenspunkter för operatorerna " && ", " || " och " , ". Dessa operatörer kommer garanterat att utvärderas från vänster till höger om de inte är överbelastade. Exempel. I uttrycket " " utvärderas den vänstra operanden (" ") först; resultatet gjuts till typen och jämförs med ; om lika med , utvärderas den högra operanden (" "), annars ;*p++ != 0 && *q++ != 0*p++ != 0booltruetrue*q++ != 0false
  • sekvenspunkten för den ternära operatorn " ?: ". 1:a operanden utvärderas först; då finns följande punkt; Den 2:a operanden utvärderas endast om den 1:a operanden är lika med ; Den 3:e operanden utvärderas endast om den 1:a operanden är . Exempel. I uttrycket " " exekveras den första operanden först (" "; variabeln ökas med ); resultatet av beräkningen gjuts till typen och jämförs med ; om lika exekveras den 2:a operanden (“ ”), annars exekveras den 3:e (“ 0 ”);truefalsea == (*p++) ? (*p++) : 0*p++p1booltruetrue(*p++)
  • sekvenspunkter i uttryck:
    • istället för symbolen " " i uttryck som är separata instruktioner. Till exempel, i uttrycket " ", infogas sekvenspunkten istället för " ";;a = b;;
    • i slutet av ett uttryck skrivet efter nyckelordet ; närmare bestämt, i det ögonblick då returvärdet kommer att kopieras in i sammanhanget för den anropande funktionen. Denna sekvenspunkt beskrivs endast explicit i C++-standarden;return
    • i slutet av uttryck skrivna inom parentes efter nyckelord , , (inklusive i konstruktioner );ifswitchwhilewhiledo-while
    • i ändarna av vart och ett av de tre uttrycken för loopen ;for
  • innan du anropar funktionen. Ordningen i vilken funktionsargument utvärderas är inte definierad. Sekvenspunkten säkerställer att alla argument utvärderas innan funktionen anropas. Exempel. Tänk på uttrycket " ". Först skapas en temporär variabel med ett värde lika med värdet på variabeln ; sedan anropas operatorn "postfix ++" på variabeln (inte den temporära); slutligen anropas funktionen  med den temporära variabeln som argument. Ovanstående gäller för variabler respektive funktioner . Samtidigt, på grund av avsaknaden av en sekvenspunkt för "+"-operatören, är ordningen för att anropa funktionerna och inte definierad. Därför är ordningen för att anropa "postfix ++"-operatorerna för variablerna och inte definierad . Det vill säga när funktionen körs är det inte känt om "postfix ++"-operatorerna anropades för variablerna och . Exempel. Tänk på uttrycket " ". Ett komma mellan funktionsargument är inte en "komma"-operator och garanterar inte i vilken ordning argumentvärdena utvärderas. Ordningen i vilken funktionsargumentvärden utvärderas är inte standardiserad och beror på kompilatorimplementeringen;f( i++ ) + g( j++ ) + h( k++ )iif()jkg()h()f()g()h()ijkf()jkf( a, b, c )
  • i en deklaration med initiering vid tidpunkten för slutförandet av beräkningen av initieringsvärdet. Exempel. Tänk på uttrycket " ". Sekvenspunkten infogas efter att uttrycket " " har utvärderats;int a = ( 1 + i++ );( 1 + i++ )
  • innan du ringer en överbelastad operatör i C++. Sekvenspunkten säkerställer att värdena för en operators argument (precis som en vanlig funktion) utvärderas innan den anropas.

Se även

Länkar

Anteckningar