C ve C++11 Incelemeler 1


#1

Bu yazilarim aslinda seri olarak gidecek. Sektorde C/C++ aktif olarak kullanmasamda zaman buldukca beyin acmak icin arastiriyorum, ugrasiyorum, C/C++ yeni standartlarina bakiyorum. Bunlardan edindigim bilgiler, kendi elestirilerime katarak bloguma yazmak istedim. Bu degerlendirmeleri ve yaziyi yazarken daha cok madde madde gidicem. Her madde uzerine tartisabiliriz, bunlari isterseniz yorum olarak yazabilir yada sosyal aglardan bir turlu ulasip muhabbet edebiliriz.

C++11 standartlari ile beraber dil buyuklugu neredeyse 2 katina cikti. C++ zaten buyuk bir dildi, 11 standartlariyla beraber cokca iyi ve kotu yorumlar aldi. Ama su atlaniyor ki C++ dilinin amaci zaten kucuk bir dil olmak degil. Bu bakimdan 11 standartlariyle beraber tamamen yeni bir dil oldu diyebiliriz.

C++ dilinin en ovundugu alanlardan biri data abstraction(veri soyutlama).

C++ yazarken dil programcilara su esnekligi veriyor, ister OOP kullan, ister prosedurel yaz, istersen coklu paradigmali yaz farketmiyor.

C ve C++ dil buyuklugu, derleyici buyuklugu zaten tartisilamaz. C dilinin amaci kucuk bir dil olmasi. Yani derleyici kontrolleri fazla degildir, bu da demek oluyor ki hata yapmaya daha acik bir dil. Bu yuzden gelistiricilerin kodu yazarken diger dillerden daha fazla dikkatli olmasi gerektigi. Kontrollerin az olmasinin amacida az once soyledigim gibi derleyiciyi kucuk tutma cabalari.

C++ icinde ki C daha guvenlidir. Cunku derleme zamani kontrolleri daha fazladir.

C dilinde kullandigimiz pointer kavrami C++ da yerlerini referanslara birakiyor. Referans ve Pointerlar arasinda ki farklari ve konuyu ilerde bir makale de daha ayrintili bir sekilde yazicam.

C++ dilinde diziler cok nadir kullanilirlar, bunun yerine vektor yada array sarmalayicilari kullanilir. Ornegin C de char str[100] yazi tutar, C++ dilinde bunu kullanmayacagiz, string sinifini kullanacagiz. Bu cumleden soyle bir anlam cikarmayin, C++ ta char str[] kullanamiyoruz. Hayir tabiki de kullanabiliyoruz fakat buna gerek yok.

En cok tartisilan konulardan bir tanesi C den C++ a gecerken performans kaybediyormuyuz? PERFORMANS KAYBETMIYORUZ

— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — —

C ile C++ arasinda bazi farkliliklara bakalim;

func(int x){}

implicit c, yani tur bilgisi yazmaya gerek yok, derleyici bunu isaretli int olarak anlayacaktir. C++ da bu kural iptal


Geri donus degeri ile ilgili ornegin;

int func(){} 

Bu ornek C de gecerli, C++ da gecersizdir. C derleyicisi geri donus degeri uretecegini beyan etmistir, return olmamasi bile gecerli durumdur.

int func(int x){} //C de gecerli, C++ da gecersiz
int func(int){} //C de isimlendirme mecbur, C++ degil

main fonksiyonunun geri donus degeri ve tipi mevzusu;

void main(){} 

Ilk olarak su soruyu sorabiliriz. C** de neden main fonksiyonunun geri donus degeri int ?**
Bunun sebebi exit fonksiyonuna yapilan cagridir. Non-zero basarisizlik, zero ise basari olarak kabul edilir. stdlib exit_clear, exit_success
C dilinde void main yaparsak nerede basari, nerede basarisiz gorulmeyecektir.Yani main geri donus degeri kesinlikle int olarak belirtmeliyiz.

Diger bir konu C dilinde main recursive olarak cagirilabilir, C++ dilinde ise bu yasaklanmistir. C++ dilinde main fonksiyonuna return deyimi yazmaya gerek yoktur, ama gelistirici olarak return yazin. Geri donus degeri ise kesinlikle int olmalidir.

int func(){return;} // C de gecerli, C++ da gecersiz
void func(){return exp;} // C de gecersiz, C++ da gecerli

Simdi su kodu inceleyelim, C ve C++ derleyicilerinin nasil davrandiklarina bakalim;

int main()
{
    func();
}

Kodumuz bu kadar. C++ bu koda soyle yaklasir, func benim icin bir identifier yani isim, ben bir bu ismi arayayim(name lookup). Ismi bulamadiginiz soyler ve sentaks hatasini yapistirir. Yani buradan cikaracagimiz C++ derleyicisi bir isim arama yapip onu bulamamasi direk sentaks hatasidir.C dilinde ise bu gecerlidir.

C soyle davranir, bir fonksiyon bildirimi ile karsilasmasa bile, once func ismini ariyor bakti ki bulamiyor sonra func fonksiyon cagri operatorunun operandi olmusmu olmus diyor, o zaman ben bu ismi arayip bulamasam bile func benim icin bir fonksiyon ismidir diyor.Geri donus degeri int olan bir fonksiyon(yani implicit bir bildirim). Bu aslinda tehlikeli bir durum. **C++ da implicit function declaration yok, C++ dilinde fonksiyon bildirimleri zorunludur.


void func();
void foo(void);

C++ dilinde hicbir anlam farkli yoktur, icinde birsey yazsa da yazmasa da…
Ama C de boyle degil, C dilinde foo fonksiyonunun parametre degiskeni yok demektir. func isimli fonksiyon ise bilgi vermiyorum demek yani degiskeni olmadigini degil bilgi vermedigini anlariz.

Peki bilgi vermemenin onemi var mi?
Tabiki de yok bu sadece geriye uyumlulugu saglamak icin yapilmis bisi.


Bu yazi icin son tartisma ornegimiz olsun, kod soyle;

int func()
{
    printf(‘’);
    int x;
    // executable statement
    // …
}

Kodun devami var gibi dusunun. Simdi C89 standartlarina gore kural soyle yerel bildirimler bloklarin basinda yapilmalidir. Yani executable statement(yurutulebilir deyim)den sonra bildirim yapamayiz. Bu kesinlikle kotu bir kural. Zaten bu kural konulduguna da pisman olunulmus sonradan. Once su deyim mevzusunu hatilayalim, C dilinde deyimler 2ye ayriliyordu, declaration statament ve executable statament. Simdi OOP’de bu kural boyle olsaydi ileride cok buyuk sikintilar cikarabilirdi.

Oneri olarak kodun bakimi manasinda, bir ismin scope nu ne kadar daraltirsak o kodun bakimini yapmak o kadar kolay olacaktir.

Konuya geri donecek olursak artik yerel bildirimlerin blok basinda yapilmasina gerek kalmadi. C++ dilinde artik gerekli yerlerde degisken tanimlamasi yapilabilir, boyle de yapilmasi gereklidir. Burada diger onemli bir konu omur konusu aslinda. Yerel degiskenler C de otomatik omurlude olabilir, statik omurlude olabilir. Statik omurlu demek programin basindan sonuna kadar bellek alanini korumasidir. Neler statik omurluydu hatirlayalim, global degiskenler, static keywordu ile tanimlananlar, fonksiyonlar ve stringler. Otomatik omurlu nesnelere ilk deger vermessek, garbage value ile hayata baslar. Cop degerler hayata baslamanin zarari yok, zarari ne zaman var eger onu cop degerle kullanirsak. Bu aslinda bildirimin blok basinda yapilmasinin bir zorlamasi. C++ da suna alismaliyiz, eger cok onemli bir nedeni yoksa tum nesnelere ilk deger vererek hayata baslatin. Gene bu bildirim ile ilgili fazlaca kullandigimiz bir yer daha var, for donguleri, dongu degiskeni. Ornegin
for(int k=0;….) C99 da bu eklenmistir, boyle kullanabiliyoruz. C++ da tabiki de bunu boyle kullanabiliyoruz. Java, C# gibi diller bu olayi C++ dan biraz daha once gorup eklemisler. Simdi bu kural olmasaydi ornegin C89 da kullaniyor gibi dusunelim, bize zarari nedir? Oncelikle scope unu gereksiz yere genisletiyor, ayni zamanda program sonuna kadar bu degisken visible durumdadir. Ama yeni kurala gore for parantezi icinde tanitilan degiskenin omru dongunun blogunun sonuna kadardir.

Zaman buldukca boyle incelemeler devam ederim :slight_smile: Tartisalim, ogrenelim…

Kaynak: http://goo.gl/kT9Nar