Typ kval

I programmeringsspråken C , C++ och D är en typkvalificerare ett nyckelord som tillämpas på en typ , vilket resulterar i en kvalificerad typ. Till exempel är const int en kvalificerad typ som representerar ett konstant heltal, medan int är motsvarande okvalificerade typ, helt enkelt ett heltal. I D är dessa kända som typkonstruktörer , i analogi med konstruktörer i objektorienterad programmering .

Typkvalificerare är ett sätt att uttrycka ytterligare information om ett värde genom typsystemet och säkerställa korrekt användning av data. Typkvalificerare används i allmänhet inte utanför C/C++-familjen av språk: många språk har en notation av konstanter, men uttrycker detta genom att namnbindningen är konstant (en " variabel som inte varierar"), snarare än genom typsystemet ; se alternativ nedan.

Efter språk

C/C++

Från och med 2014 och C11 finns det fyra typkvalificerare i standard C: const ( C89 ), volatile ( C89 ), restrict ( C99 ) och _Atomic ( C11 ) – det senare har ett privat namn för att undvika att krocka med användardefinierade namn. De två första av dessa, const och volatile , finns också i C++ och är de enda typkvalificerarna i C++. Sålunda i C++ används termen " cv -kvalificerad typ" (för c onst och v olatile) ofta för "kvalificerad typ", medan termerna " c -kvalificerad typ" och " v -kvalificerad typ" används när endast en av kvalet är relevant.

Av dessa är const den överlägset mest kända och mest använda, som förekommer i C- och C++- standardbiblioteken och påträffas i all betydande användning av dessa språk, vilket måste uppfylla const-correctness . De andra kvalificeringarna används för programmering på låg nivå, och även om de används i stor utsträckning där, används de sällan av typiska programmerare. Under en tid användes dock volatile av vissa C++-programmerare för synkronisering under trådning, även om detta avskräcktes och nu är trasigt i de flesta kompilatorer.

D

I D är typkonstruktörerna const , immutable , shared och inout . immutable är en starkare variant av const , vilket indikerar data som aldrig kan ändra sitt värde, medan const indikerar data som inte kan ändras genom denna referens: det är en konstant syn på eventuellt föränderlig data. shared används för delad data i multi-threading (som volatile kort använts för i C++). inout är ett jokertecken som används för att tillåta funktioner som inte modifierar data (och därför bara handlar om den okvalificerade typen av data) att returnera samma kvalificerade typ som indata. const och immutable kan också användas som lagringsklassspecifikatorer.

Syntax

I C och C++ ges en typ i en funktionsdeklaration eller variabeldeklaration genom att ge en eller flera typspecifikationer, och eventuellt typkvalificerare. Till exempel kan en heltalsvariabel deklareras som:

  int  x  ; 

där int är typspecifikationen. En heltalsvariabel utan tecken kan deklareras som:

   osignerad  int  x  ; 

där både unsigned och int är typspecifikatorer. En konstant heltalsvariabel utan tecken kan deklareras som:

    const  unsigned  int  x  ; 

där const är en typkvalificerare, där den kvalificerade typen av x är const unsigned int och den okvalificerade typen är unsigned int .

Variabeldeklarationer har vidare en valfri lagringsklassspecifikator . Detta är egentligen ett separat ämne, skilt från typen, även om const på en variabeldeklaration också anses ha konsekvenser för lagringsklassen, nämligen att den kan lagras i skrivskyddat minne.

Flyktiga-korrekthet

Den andra kvalificeringen i C och C++, volatile , indikerar att ett objekt kan ändras av något externt till programmet när som helst och måste därför läsas om från minnet varje gång det nås.

Kvalificeraren finns oftast i kod som manipulerar hårdvara direkt (som i inbyggda system och enhetsdrivrutiner ) och i flertrådade applikationer (även om de ofta används felaktigt i det sammanhanget; se externa länkar på volatile variabel ). Det kan användas på exakt samma sätt som const i deklarationer av variabler, pekare, referenser och medlemsfunktioner, och faktiskt, volatile används ibland för att implementera en liknande design-by-contract-strategi som Andrei Alexandrescu kallar volatile -correctness, även om detta är mycket mindre vanligt än const -korrekthet. Det flyktiga kvalet kan också tas bort av const_cast , och det kan kombineras med const- kvalet som i detta exempel:



       

    
        

    // Sätt upp en referens till ett skrivskyddat maskinvaruregister som är  // mappat i en hårdkodad minnesplats.  const  volatile  int  &  hardwareRegister  =  *  reinterpret_cast  <  int  *>  (  0x8000 )  ;  int  currentValue  =  hardwareRegister  ;  // Läs minnesplatsen  int  newValue  =  hardwareRegister  ;  // Läs det igen  hardwareRegister  =  5  ;  // Fel, kan inte skriva till en const-plats 

Eftersom hardwareRegister är flyktigt finns det ingen garanti för att det kommer att hålla samma värde vid två på varandra följande läsningar även om programmeraren inte kan ändra det. Semantiken här indikerar att registrets värde är skrivskyddat men inte nödvändigtvis oförändrat.

Historia

Begreppet typkvalifierare introducerades, tillsammans med exemplet på readonly (senare omdöpt till const ) av Bjarne Stroustrup i ett internt tekniskt memorandum från Bell Labs från 1981, och implementerades i C med Classes , föregångaren till C++ . När det gäller motivation skriver Stroustrup:

"Det tjänade två funktioner: som ett sätt att definiera en symbolisk konstant som lyder räckvidds- och typregler (det vill säga utan att använda ett makro) och som ett sätt att anse att ett objekt i minnet är oföränderligt."

const antogs sedan i C som en del av standardiseringen, och visas i C89 (och efterföljande versioner) tillsammans med en annan typkvalificerare, volatile , som uppfanns av ANSI C-standardkommittén (X3J11). volatile dök upp 1985; och en tidig användning var att kompilera UNIX-kärnan för MIPS , för att möjliggöra optimerad kompilering genom att förhindra att vanliga optimeringar tillämpas på flyktiga variabler. En ytterligare kvalificering, noalias , föreslogs vid mötet i december 1987 i X3J11-kommittén, men avvisades; dess mål uppfylldes i slutändan av limit -kvalet i C99. Motivationen för noalias var ett komplement till volatile , nämligen att det indikerade att även normalt osäkra optimeringar kunde utföras. Ritchie var inte särskilt stödjande av typkvalificerare, och hävdade att de inte "bar sin vikt", men i slutändan argumenterade inte för att de skulle tas bort från standarden; han motsatte sig noalias , och det togs bort från utkastet.

Java har inga typbeteckningar och påfallande utelämnade const : ett förslag från 1999 att lägga till det avvisades, särskilt för att det skulle ha brutit kompatibiliteten att lägga till det i efterhand och sedan ändra standardbiblioteket för att använda det konsekvent. Java lämnade dock initialt möjligheten att implementera const öppen , märkbart genom att const är ett reserverat ord , även om det faktiskt inte används som ett nyckelord . Istället har Java det objektorienterade nyckelordet final , som används för att kvalificera attribut (och därmed även för lokala variabler) som konstant, men inte för att kvalificera typer.

Alternativ

Andra språk har ett annat tillvägagångssätt, eftersom beständighet är en egenskap hos en identifierare (eller namnbindning ), inte en typ. Sådana språk har alltså konstanta identifierare (motsvarande "variabler" som inte varierar) med enstaka tilldelning, men har inte en föreställning om konst-korrekthet: eftersom beständighet inte är en del av typen finns det ingen möjlighet till typfel. Exempel inkluderar Ada 83 med konstanta objekt och ett konstant nyckelord, och Java med det sista nyckelordet.

Anteckningar

externa länkar