Udefinert oppførsel
I programmering er udefinert oppførsel resultatet av å kjøre kode som ikke har en definert oppførsel av språkspesifikasjonen som koden forholder seg til.[1] Både C og C++ er språk hvor oppførselen noen ganger er udefinert. I standarden til disse språkene står semantikken for enkelte operasjoner som udefinert. En kompilator har lov til å anta at slike operasjoner aldri vil finne sted i koden. Implementasjonen av kompilatoren vil anses som korrekt uansett hva den definerer oppførselen til å være i tilfellet hvor kode har udefinert oppførsel. Dette gir stor fleksibilitet til de som skal skrive kompilatorer, da det tillater kompilatoren ofte å gjøre betydelige optimiseringer. Det er programvareutviklerens ansvar å skrive kode som ikke har udefinert oppførsel, selv om kompilatoren har lov til å diagnostisere problemet når det skjer.
Eksempler på udefinert oppførsel
[rediger | rediger kilde]Det å modifisere et «string literal» er udefinert oppførsel [2]
char *p = "wikipedia";
p[0] = 'W'; // Dette er udefinert oppførsel
Heltallsdivisjon med 0 er også udefinert oppførsel [3]
int res = 5/0;
Modifisere et objekt flere ganger mellom to sekvenspunkt er også udefinert oppførsel.[4] Et sekvenspunkt er et punkt i programmet hvor alle sideeffekter ved tidligere evalueringer skal være gjennomført og ingen sideffekter av kommende evalueringer skal ha funnet sted. Et semikolon er et eksempel på et sekvenspunkt. Det er verdt å nevne at her er det visse forskjeller mellom C og C++ på hva som er udefinert oppførsel i henhold til sekvenspunkter, særlig etter versjonsstandarden C++11.[1] Men dette tilfellet vil være udefinert oppførsel i begge.
int i = 5;
i = i++ + 1; // Dette er udefinert oppførsel
Når man modifiserer et objekt mellom to sekvenspunkt vil også det å lese verdien for noe annet formål enn å bestemme verdien som skal lagres være udefinert oppførsel.[5] I det første eksempelet gjelder det variabelen i, som leses i «a[i]» men for et annet formål enn å bestemme verdien til i. Mellom sekvenspunktene endres også verdien av i, som dermed fører til udefinert oppførsel. Samme prinsipp ved eksempelet i andre linje.
a[i] = i++; // udefinert oppførsel
printf("%d %d", ++n, power(2, n)); // også udefinert oppførsel
Visse pekeroperasjoner er også udefinert oppførsel [6]
int arr[4] = {1, 2, 3, 4};
int *p = arr + 5; // Dette er udefinert oppførsel
Det å nå enden av et funksjonskall som skal returnere en verdi er også udefinert oppførsel [7]
int funk() {
}
printf("%d", funk()); // udefinert oppførsel
Referanser
[rediger | rediger kilde]- ^ a b «Order of evaluation - cppreference.com». en.cppreference.com. Besøkt 9. august 2016.
- ^ ISO/IEC (2003). ISO/IEC 14882:2003(E): Programming Languages - C++ §2.13.4 String literals [lex.string] para. 2
- ^ ISO/IEC (2003). ISO/IEC 14882:2003(E): Programming Languages - C++ §5.6 Multiplicative operators [expr.mul] para. 4
- ^ ANSI X3.159-1989 Programming Language C, footnote 26
- ^ ISO/IEC (1999). ISO/IEC 9899:1999(E): Programming Languages - C §6.5 Expressions para. 2
- ^ ISO/IEC (2003). ISO/IEC 14882:2003(E): Programming Languages - C++ §5.7 Additive operators [expr.add] para. 5
- ^ ISO/IEC (2007). ISO/IEC 9899:2007(E): Programming Languages - C §6.9 External definitions para. 1