PDA

Tam Sürümünü Görmek İçin : Undefined Behaviour


quasimodo
02/05/2008, 00:25
int c;

cout << c++ << c;
undefined behaviour mı?


acehreli
02/05/2008, 13:02
Orada bir tanimsiz davranis var ama senin sordugun konu yuzunden degil. :) Tanimsiz davranis, c'yi ilk degeri verilmeden kullandigin icin oluyor. Onun icin ornegin soyle yazdigini varsayiyorum:

int c = 0;

Senin sordugun soru tanimsiz davranis (undefined behavior) degil, belirsiz davranistir (unspecified behavior).

cout << c++ << c;

Ifadesini soyle acabiliriz

operator<<(operator<<(cout, c++), c);

Okumayi kolaylastirmak icin operator<< fonksiyonlarini ayni olsalar bile 'f' ve 'g' diye yazarsak:

f(g(cout, c++), c);

(Orada f ve g ayni fonksiyon: operator<<. Cagrilari ayirdedebilmek icin ayri yazdim.)

Standart sunlari sart kosar:

- Bir fonksiyon cagrilmadan once butun parametre degerlerinin hesaplanmasi gerekir (cok mantikli!)

- Parametrelerin hangi sirada hesaplanacaklari belirsizdir (unspecified)

- Parametreler ayni anda isletilemezler (C'de de C++'ta da es zamanli isletim yoktur)

Ikinci neden yuzunden su ifadede y()'nin mi yoksa z()'nin mi once isletilecegi belirsizdir (bu yuzden yanilmiyorsam Microfost ve gcc degisik sira kullanirlar):

x(y(), z());

y(), z(), x() sirasi da yasaldir; z(), y(), x() de...

Bizim ornegimizde standardin istegi dogrultusunda olaylar sunlara uyarak gelismek zorundadir:

- cout ve c++ g()'den once ama belirsiz sirada
- g() ve c f'()'den once ama belirsiz sirada

Iki ornek davranis:

1) Yazildigi sirada:

cout
c++ // g'de 0 kullanilacak ama c==1
g() // 0 yazilir
c // f'de 1 kullanilacak
f() // 1 yazilir


2) En ters sirada

c // g'de 0 kullanilacak
c++ // f'de 0 kullanilacak ama c==1
cout
g() // 0 yazilir
f() // 0 yazilir


3) vs.
4) diger vs. :)

Standart, parametrelerin isletilmesi konusunda sira noktalari (sequence point) tanimladigi icin, burada c'nin kullaniminda tanimsiz davranis yok. Hersey sirayla olmak zorunda ama o siranin ne oldugu belirsiz (unspecified).

Ali