Slijedna točka
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++ != 0
su 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++) : 0
postoji 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
-while
naredbe, 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++)
,f
je pozvan s parametrom originalne vrijednosti varijablei
, alii
je inkrementiran prije ulaska u tijelo funkcijef
. Slično tome,j
ik
su ažurirani prije ulaska ug
ih
. Međutim, nije specificirano kojim redoslijedom se izvršavajuf()
,g()
ih()
, niti kojim redoslijedom sui
,j
ik
inkrementirani. Vrijednosti varijablij
ik
u tijelu funkcijef
su prema tome nedefinirane. [3] Primijetite da pozivf(a,b,c)
ne predstavlja uporabu zarez operatora i da redoslijed evaluacije zaa
,b
, andc
nije 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
5
u 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
j
unutarf
dakle invocira nedefinirano ponašanje. - ↑ C++ standard, ISO 14882:2003, odjeljak 1.9, fusnota 11.
- Pitanje 3.8 u FAQ-u za comp.lang.c