Slijedna točka u imperativnom programiranju definira bilo koju točku u izvršavanju računalnog programa na kojoj je zajamčeno da su na djelu svi nusefekti prijašnjih evaluacija i da nisu na djelu nusefekti budućih evaluacija. Često su spominjane vezano uz C ili C++, jer rezultat nekih izraza može ovisiti o redoslijedu evaluacije njihovih podizraza. Dodavanje jedne ili više slijednih točaka metoda je osiguravanja konzistentnih rezultata, jer se time ograničavaju mogući redoslijedi evaluacije.
Primjeri dvosmislenosti
Pogledajmo dvije funkcije f() i g(). U programskim jezicima C i C++ + operator nije slijedna točka, i prema tome je u izrazu f()+g() moguće da će najprije biti izvršen ili f() ili g(). Zarez operator je slijedna točka, pa je stoga u kodu f(),g() redoslijed evaluacije definiran (tj. najprije je pozvan f(), a zatim je pozvan f()). Tip i vrijednost cijelog izraza je vrijednost od g(); vrijednost od f() se odbacuje.
Slijedne točke treba razmatrati i kada je ista varijabla modificirana više od jednom unutar istog izraza. Često citiran primjer je izraz i=i++, koji ujedno i pridružuje i samome sebi i inkrementira i. Konačna vrijednost od i je upitna, jer, ovisno o semantici jezika, inkrement se može pojaviti prije, poslije ili paralelno s pridruživanjem. Definicija pojedinog jezika može specificirati jednog od mogućih ponašanja, ili jednostavno opisati ovo ponašanje kao nedefinirano. U programskim jezicima C i C++ evaluacija takvog izraza daje nedefinirano ponašanje.
Slijedne točke u programskim jezicima C i C++
U programskim jezicima C[1] i C++[2], slijedne točke se pojavljuju na sljedećim mjestima. (U C++u, preopterećenje operatora se ponaša kao funkcija, pa prema tome operatori, koji su preopterećeni, uvode slijedne točke jednako kao što to čine regularni pozivi funkcije.)
- Između evaluacije lijevog i desnog operanda operatora
&&(logičko I), operatora||(logičko ILI) i operatora zarez. Na primjer, u izrazu*p++ != 0 && *q++ != 0, sve posljedice podizraza*p++ != 0su završene prije bilo kakvog pokušaja pristupanja varijabliq. - Između evaluacije prvog operanda ternarnog operatora ("upitnik") i drugog ili trećeg operanda. Na primjer, u izrazu
a = (*p++) ? (*p++) : 0postoji slijedna točka nakon prvog podizraza*p++, što znači da je već inkrementiran do izvršavanja drugog podizraza. - Na kraju punog izraza. Ova kategorija uključuje naredbe s izrazima (kao što je pridruživanje
a=b;), return naredba, kontrolni izraziif,switch,while, ilido-whilenaredbe, i sva tri izraza u for naredbi. - Prije ulaska u funkciju u pozivu funkcije. Redoslijed kojim su argumenti evaluirani nije specificiran, ali ova slijedna točka znači da su svi nusefekti završeni prije ulaska u funkciju. U izrazu
f(i++) + g(j++) + h(k++),fje pozvan s parametrom originalne vrijednosti varijablei, aliije inkrementiran prije ulaska u tijelo funkcijef. Slično tome,jiksu ažurirani prije ulaska ugih. Međutim, nije specificirano kojim redoslijedom se izvršavajuf(),g()ih(), niti kojim redoslijedom sui,jikinkrementirani. Vrijednosti varijablijiku tijelu funkcijefsu prema tome nedefinirane. [3] Primijetite da pozivf(a,b,c)ne predstavlja uporabu zarez operatora i da redoslijed evaluacije zaa,b, andcnije specificiran. - Na povratku iz funkcije, nakon što je povratna vrijednost kopirana u kontekst poziva. (Ova slijedna točka je specificirana samo u C++ standardu; prisutna je samo implicitno u C-u[4].)
- Na kraju inicijalizatora; na primjer, nakon evaluacije od
5u deklaracijiint a = 5;.
Reference
- ↑ Dodatak C C99 specifikacije navodi okolnosti po kojima se slijedne točke mogu podrazumijevati.
- ↑ C++ standard iz 1998. navodi slijedne točke za taj jezik u odjeljku 1.9, paragraf 16–18.
- ↑ Klauzula 6.5#2 C99 specifikacije: "Između prethodne i sljedeće slijedne točke objektu će vrijednost koju sprema biti promijenjena najviše jednom u evaluaciji izraza. Nadalje, prijašnjoj vrijednosti će se pristupiti isključivo radi određivanja vrijednosti koja treba biti spremljena." Pristupanjem vrijednosti od
junutarfdakle invocira nedefinirano ponašanje. - ↑ C++ standard, ISO 14882:2003, odjeljak 1.9, fusnota 11.
- Pitanje 3.8 u FAQ-u za comp.lang.c