Waypoint

Den aktuelle version af siden er endnu ikke blevet gennemgået af erfarne bidragydere og kan afvige væsentligt fra den version , der blev gennemgået den 9. november 2016; checks kræver 7 redigeringer .

Sekvenspunkt - i programmering , ethvert  punkt i programmet, hvor det er garanteret, at alle bivirkninger fra tidligere beregninger allerede er dukket op, og bivirkningerne af efterfølgende er stadig fraværende.

Sekvenspunkter nævnes ofte, når man taler om sprogene C og C++ . På disse sprog er det muligt at skrive et udtryk, hvis evalueringsrækkefølge af underudtryk ikke er defineret af standarderne og påvirker resultatet. Tilføjelse af et eller flere sekvenspunkter giver dig mulighed for at garantere evalueringsrækkefølgen i nogle tilfælde.

Det er værd at bemærke, at tilgangen til at strømline processen med at evaluere udtryk baseret på sekvenspunkter oprindeligt opfyldte C-sprogets behov ganske godt, men ikke var tilstrækkelig til C++-sproget, hvor det sæt af operatorer, der returnerede lvalue- resultater, var betydeligt udvidet. Og med fremkomsten af ​​behovet for sprogunderstøttelse til multithreading i C og C++, måtte bestilling baseret på sekvenspunkter helt opgives. Moderne C- og C++-sprogspecifikationer beskriver rækkefølgen af ​​processen med at evaluere udtryk gennem relationer, ordnet før ( sekventeret før ) og ordnet efter ( sekventeret efter ). Startende med C++11 -standarden eksisterer begrebet et sekvenspunkt ikke længere i C++-sproget . I C har forestillingen om et sekvenspunkt overlevet den dag i dag, men siden C11 -standarden , ikke som et grundlæggende begreb, men kun som en kombination af relationer ordnet før og bestilt efter .

C++11-standarden , såvel som efterfølgende C++14- og C++17-standarder , introducerede en lang række yderligere ordrer til C++-sprogoperatørerne baseret på den nye model, hvilket førte til, at mange udtryk, hvis adfærd var udefineret i C ++98 , fik en veldefineret adfærd i moderne C++. I dag overstiger strengheden ved at bestille processen med at evaluere udtryk i C++-sproget betydeligt den i C-sproget.

Eksempler på tvetydighed i C og C++

Når der er uklarheder, er C- og C++-sprogstandarderne:

  1. angive flere acceptabel adfærd blandt de mulige (se uspecificeret adfærd );
  2. angive den eneste acceptable adfærd blandt de mulige eller
  3. angiver eksplicit, at adfærden er udefineret (se udefineret adfærd ).

Eksempel 1: Uspecificeret adfærd.

g () + f ()

Operatoren " " er ikke et sekvenspunkt, så det vides ikke, hvilken af ​​funktionerne der kaldes først: eller . Adfærden afhænger af implementeringen af ​​compileren . +f()g()

Eksempel 2: Den eneste acceptable adfærd.

f (), g ()

Operatøren " " er et sekvenspunkt, så rækkefølgen af ​​evaluering er garanteret af standarden og kendt på forhånd (fra venstre mod højre): ,

  • den venstre operand evalueres først: funktionen kaldes ;f()
  • derefter den rigtige: funktionen hedder .g()

Eksempel 3: Udefineret adfærd.

i = i ++

Fra C-sprogets synspunkt indeholder det angivne udtryk flere modifikationer af variablen , ikke ordnet i forhold til hinanden. Dette udtryks adfærd er udefineret. (På samme tid, set fra det moderne C++-sprog, som strømliner processen med evaluering af opgaveoperatøren meget mere strengt, er adfærden af ​​dette udtryk fuldstændigt defineret.) i

Sekvenspunkter i C og C++

Følgende sekvenspunkter blev defineret i de originale C- og C++-sprogstandarder:

  • sekvenspunkter for operatorer " && ", " || " og " , ". Disse operatører er garanteret evalueret fra venstre mod højre, medmindre de er overbelastede. Eksempel. I udtrykket " " evalueres den venstre operand (" ") først; resultatet støbes efter typen og sammenlignes med ; hvis lig med , evalueres den højre operand (" ") ellers ;*p++ != 0 && *q++ != 0*p++ != 0booltruetrue*q++ != 0false
  • sekvenspunktet for den ternære operator " ?: ". 1. operand evalueres først; så er følgende punkt placeret; Den 2. operand evalueres kun, hvis den 1. operand er lig med ; Den 3. operand evalueres kun, hvis den 1. operand er . Eksempel. I udtrykket “ ” udføres den 1. operand først (“ ”; variablen øges med ); resultatet af beregningen støbes til typen og sammenlignes med ; hvis lig , udføres den 2. operand (“ ”), ellers den 3. (“ 0 ”);truefalsea == (*p++) ? (*p++) : 0*p++p1booltruetrue(*p++)
  • sekvenspunkter i udtryk:
    • i stedet for symbolet " " i udtryk, der er separate instruktioner. For eksempel, i udtrykket " ", er sekvenspunktet indsat i stedet for " ";;a = b;;
    • i slutningen af ​​et udtryk skrevet efter nøgleordet ; mere præcist på det tidspunkt, hvor returværdien vil blive kopieret ind i konteksten af ​​den kaldende funktion. Dette sekvenspunkt er kun eksplicit deklareret i C++-standarden;return
    • i slutningen af ​​udtryk skrevet i parentes efter nøgleord , , (også i konstruktioner );ifswitchwhilewhiledo-while
    • i enderne af hvert af de tre udtryk for løkken ;for
  • før du kalder funktionen. Den rækkefølge, som funktionsargumenter evalueres i, er ikke defineret. Sekvenspunktet sikrer, at alle argumenter evalueres, før funktionen kaldes. Eksempel. Overvej udtrykket " ". Først oprettes en midlertidig variabel med en værdi svarende til værdien af ​​variablen ; så kaldes "postfix ++" operatoren på variablen (ikke den midlertidige); til sidst kaldes funktionen  med den midlertidige variabel som argument. Ovenstående gælder for henholdsvis variabler og funktioner . På samme tid, på grund af manglen på et sekvenspunkt for "+"-operatøren, er rækkefølgen for at kalde funktionerne , og ikke defineret. Derfor er rækkefølgen for at kalde "postfix ++" - operatorerne for variablerne og ikke defineret . Det vil sige, når funktionen udføres, vides det ikke, om "postfix ++"-operatorerne blev kaldt for variablerne og . Eksempel. Overvej udtrykket " ". Et komma mellem funktionsargumenter er ikke en "komma"-operator og garanterer ikke den rækkefølge, som argumentværdier evalueres. Rækkefølgen, hvori funktionsargumentværdier evalueres, er ikke standardiseret og afhænger af compilerimplementeringen;f( i++ ) + g( j++ ) + h( k++ )iif()jkg()h()f()g()h()ijkf()jkf( a, b, c )
  • i en erklæring med initialisering på tidspunktet for afslutning af beregningen af ​​initialiseringsværdien. Eksempel. Overvej udtrykket " ". Sekvenspunktet indsættes efter udtrykket " " er blevet evalueret;int a = ( 1 + i++ );( 1 + i++ )
  • før du ringer til en overbelastet operatør i C++. Sekvenspunktet sikrer, at værdierne af en operators argumenter (ligesom en almindelig funktion) evalueres, før den kaldes.

Se også

Links

Noter