|
|
Bu makalenin farkl� dillerde bulundu�u adresler: English Castellano ChineseGB Deutsch Francais Italiano Portugues Russian Turkce Arabic |
taraf�ndan Lorne Bailey <sherm_pbody(at)yahoo.com> Yazar hakk�nda: Lorne �ikago da ya��yor ve Oracle veritabanlar�ndan veri alma-girme konusunda uzmanla�m�� bir bilgisayar dan��man�d�r. Unix ortam�nda programlama yapmaya ba�lad���ndan beri, Lorne 'DLL Cehennemi' nden tamam�yla ka��nm��t�r. Halen Bilgisayar Bilimleri'nde y�ksek lisans� i�in �al��maktad�r. T�rk�e'ye �eviri: B�lent �ZDEM�R <bulentozdem(at)hotmail.com> ��erik: |
�zet:
Bu yaz�, sizin C dilinin temellerini bildi�inizi varsayarak
derleyici olarak gcc kullan�m�n� size tan�tacakt�r. Basit C kaynak
kodlar�n�z i�in derleyiciyi komut sat�r�ndan �a��rabileceksiniz.
Daha sonra, asl�nda neler oldu�una ve programlar�n�z�n
derlenmesini nas�l denetleyebilece�inize h�zl�ca bir g�z ataca��z.
Bu arada hata ay�klay�c�lar�n kullan�m�na da �ok k�sa de�inece�iz.
Serbest bir yaz�l�m�n kapal� ve tescilli bir derleyici ile derlendi�ini
d���nebilir misiniz? Program�n�z�n �al��an k�sm�na neler olaca��n� nereden
bilebilirsiniz? Herhangi bir 'arka kap�' veya Truva At� vir�s� olabilir.
Ken Thompson, t�m zamanlar�n en b�y�k hack lerinden birinde, 'login'
program�n�n i�ine bir arka kap� koyan ve derleyici kendisini
derlemeye ba�lad���n� anlad��� zaman kendisini koruyan bir
derleyici yazm��t�r. Bu t�m zamanlar�n klasi�ini, kendi tan�mlamas�ndan,
bu adresten okuyabilirsiniz.
�ansl�y�z ki, gcc var. Bir configure; make; make install
yapt���n�zda,
gcc sahne arkas�nda bir�ok a��r i�i sizin i�in yapmaktad�r.
gcc'nin bizim i�in �al��mas�n� nas�l sa�lar�z?
Bir kart oyunu yazmaya ba�layaca��z, ancak derleyicinin fonksiyonlar�n�
gosterecek kadar�yla yetinece�iz. S�f�rdan ba�layaca��mdan, bir
�al��t�r�labilir program yarat�labilmesi i�in
derleyicinin neler yapmas� gerekti�ini ve bunlar� hangi s�rada
yapt���n� anlamam�z gerekiyor. Bir C program�n�n nas�l derlendi�ine
ve gcc'nin bizim istediklerimizi yapmas� i�in gereken se�eneklerine
bakaca��z.
Ad�mlar (ve bu ad�mlar� ger�ekle�tiren ara�lar) �unlard�r:
�n-derleme (gcc -E),
Derleme (gcc),
Toplama (as),
ve Ba�lama (ld).
�lk �nce, derleyici nas�l �al��t�raca��m�z� bilmeliyiz. T�m zamanlar�n klasi�i olan ilk C program� ile ba�layaca��z. (Deneyimliler beni affetmek zorunda).
#include <stdio.h> int main()
{ printf("Hello World!\n"); }
Bu dosyay� game.c
olarak kayded�n. Program�, komut sat�r�nda:
yazarak derleyebilirsiniz.
C derleyicisi, benimsenmi� olarak, a.out
isimli �al��t�r�labilir program olu�turur.
Bunu, ��yle �al��t�rabilirsiniz:
a.out Hello WorldHer derleme yapt���n�zda yeni
a.out
eskisinin �zerine
yaz�lacakt�r. Bu y�zden, a.out
dosyas�n� hangi program�n
olu�turdu�unu bilemezsiniz. Bu problem�, gcc'ye �al��t�r�labilir ismini
-o
se�ene�i ile s�yleyerek ��zebiliriz. Bu program�
game
olarak adland�raca��z, ama, C, Java gibi isimlendirme
s�n�rlamas� gerektirmedi�inden herhangi bir isim de verebiliriz.
gcc -o game game.c
game Hello World
Bu noktada, �ok faydal� bir programa sahip olmaktan hayli uza��z. Bunun k�t� bir�ey oldu�unu d���n�yorsan�z, derlenmi� ve �al��an bir program�m�z oldu�u ger�e�ini an�msayabilirsiniz. Bu programa k���k k���k eklemeler yapt�k�a, program�n hala �al���r oldu�undan emin olmak isteyece�iz. �yle g�r�n�yor ki, her yeni ba�layan programc� 1,000 sat�rl�k kaynak kod yaz�p tek seferde d�zeltmeleri yapmak ister. Kimse, evet kimse, bunu yapamaz. �al��an k�c�k bir program yazars�n�z, de�i�iklikleri yapars�n�z ve tekrar �al��abilir hale getirirsiniz. Bu, tek seferde d�zeltmeniz gereken hata say�s�n� s�n�rlar. Art�, son olarak ne yapt���n�z� bildi�inizden, �al��mama durumunda nereye odaklanaca��n�z� bilirsiniz. Bu �al��aca��n� sizin d���nd���n�z, derlenen, ama �al��mayan bir�ey yapmaktan sizi al�koyar. Hat�rlay�n, derlenebilir olmas� dogru oldu�u anlam�na gelmez.
Bir sonraki ad�m�m�z oyunumuz i�in bir ba�l�k dosyas� olu�turmak. Bir ba�l�k dosyas� tek bir yerde, veri tipleri ve fonksiyon tan�mlamalar� i�in kullan�l�r. Bu veri yap�lar�n�n tutarl� bir �ekilde tan�mlanmas�n� sa�lar ki, b�ylece program�n her k�sm� her�eyi ayn� �ekilde tan�r.
#ifndef DECK_H #define DECK_H #define DECKSIZE 52 typedef struct deck_t { int card[DECKSIZE]; /* number of cards used */ int dealt; }deck_t; #endif /* DECK_H */
Bu dosyay� deck.h
olarak kaydedin. Sadece .c
dosyalar�
derlenebilir, bu y�zden game.c program�m�z� de�i�tirece�iz.
game.c dosyas�n�n ikinci sat�r�na, #include "deck.h"
yaz�n.
Be�inci sat�ra, deck_t deck;
yaz�n. Herhangi bir
yanl�� yapmad���m�zdan emin olmak i�in yeniden derleyin.
gcc -o game game.c
Hata yok, problem yok. Derlenmezse, derlenene kadar uzerinde �al���n.
Derleyici deck_t
tipini nereden biliyor?
��nk� �n-derleme s�ras�nda, "deck.h" dosyas� "game.c"
dosyas�na kopyalan�r. Kaynak kodun i�erisinde �nderleyici komutlar�n�n
�n�ne # konulur. gcc'yi -E
anahtar� ile kullanarak
�n-derleyiciyi �a��rabilirsiniz.
gcc -E -o game_precompile.txt game.c wc -l game_precompile.txt 3199 game_precompile.txtHemen hemen 3200 sat�r ��kt�! B�y�k �o�unlu�u
stdio.h
include dosyas�, fakat bakt���n�zda, bizim tan�mlamalar�m�z da
orada. E�er -o
anahtar� ile bir ��kt� dosyas� belirtmezseniz
, ��kt�lar konsola yaz�l�r. �n-derleme i�lemi u� temel amac� ger�ekle�tirerek
kaynak koda b�y�k esneklik verir:
-E
anahtar�n� hemen hemen hi� kullanmazs�n�z,
ama b�rak�n ��kt�s�n� derleyiciye aktars�n.
Bir ara ad�m olarak, gcc kodunuzu Assembly diline �evirir. Bunu yapmak i�in, kodunuzu parse ederek ne yapmaya �al��t���nuzu ortaya ��karmas� gerekir. E�er bir yaz�m(syntax) hatas� yapm�� iseniz, bunu size s�yler ve derleme durur. �nsanlar, hatal� olarak, bu ad�m� b�t�n i�lemin kendisi gibi alg�larlar. Ancak, gcc'nin daha yapaca�� �ok i� vard�r.
as
Assembly kodunu nesne koduna �evirir. Nesne kodu
asl�nda CPU taraf�ndan �al��t�r�lamaz, ama �al��t���lmaya olduk�a yak�nd�r.
-c
derleyici anahtar� .c dosyas�n� .o uzant�l� bir nesne
dosyas�na donu�turur. E�er
gcc -c game.ckomutunu cal��t�r�rsak otamatik olarak game.o isimli bir dosya elde ederiz. Burada �nemli bir noktada dural�m. Herhangi bir .c dosyas�n� alarak bir nesne dosyas� olu�turabiliriz. A�a��da g�rece�imiz gibi, bu nesne dosyalar�n� Ba�lama ad�m� ile �al��abilir bir dosyaya toplayabiliriz. �rne�imizle devam edelim. Bir kart oyunu programl�yoruz ve ka��t destesini
deck_t
ile tan�mlad�k, �imdi ka��tlar� kar��t�racak bir fonksiyon yazaca��z.
Bu fonksiyon, deste tipine bir i�aret�i alacak ve onu, rastgele bir say� k�mesi
ile dolduracak. Hangi kartlar�n daha �nce kullanildi�ini 'drawn' dizisi ile
takip edecek. Bu dizi DECKSIZE �yelerinden birini iki kez kullanmam�z� engelliyecek.
#include <stdlib.h> #include <stdio.h> #include <time.h> #include "deck.h" static time_t seed = 0; void shuffle(deck_t *pdeck) { /* Keeps track of what numbers have been used */ int drawn[DECKSIZE] = {0}; int i; /* One time initialization of rand */ if(0 == seed) { seed = time(NULL); srand(seed); } for(i = 0; i < DECKSIZE; i++) { int value = -1; do { value = rand() % DECKSIZE; } while(drawn[value] != 0); /* mark value as used */ drawn[value] = 1; /* debug statement */ printf("%i\n", value); pdeck->card[i] = value; } pdeck->dealt = 0; return; }
Bu dosyay� shuffle.c
olarak kaydedin.
Kodun i�erisine bir hata ay�klama sat�r� koyduk, �yle ki,
program �al��t�r�ld��� zaman, bu sat�r �retilen kart
numaralar�n� yazacak. Bu program�n fonksiyona litesine
herhangi bir katk� da bulunmayacak, ama neler oldu�unu
g�rmek a��s�ndan �nemli. Hen�z oyunumuza yeni ba�lad���m�zdan
fonksiyonumuzun �al���p �al��mad���n� anlamak i�in ba�ka
yolumuz yok. printf sat�r� sayesinde �u anda tam olark ne oldu�unu
anlayabiliriz, b�ylece destemizin do�ru da��t�ld���ndan emin olarak
bir sonraki ad�ma ge�ebiliriz. �al��t���ndan iyice emin olduktan sonra,
hata ay�klama sat�r�n� programdan ��kartabiliriz. Bu hata ay�klama tekni�i �ok ham g�r�nebilir,
ama �ok k���k bir hareketle amac�m�za ula��yoruz. Daha geli�mi�
hata ay�klay�c�lar� daha sonra tart��aca��z.
shuffle.c
dosyas�nda 'main' fonsiyonu olmad���ndan
bu program� �al��t�ramay�z. Bu dosyay�, i�erisinde 'main' fonksiyonu
olan ve 'shuffle' fonksiyonu �a��r�m� yapan ba�ka bir program ile birle�tirmeliyiz.
gcc -c shuffle.ckomutunu �al��t�r�n ve
shuffle.o
dosyas� olu�tu�undan
emin olun. game.c dosyas�n� a��n, ve 7. sat�rda, deck
de�i�keni
i�in yap�lan deck_t tan�mlamas�ndan sonra,
shuffle(&deck);sat�r�n� ekleyin. �imdi, daha �nce yapt���m�z gibi �al��an program olu�turmaya �al��t���m�z zaman, hata mesaj� alaca��z:
gcc -o game game.c /tmp/ccmiHnJX.o: In function `main': /tmp/ccmiHnJX.o(.text+0xf): undefined reference to `shuffle' collect2: ld returned 1 exit statusDerleme ba�ar�l� oldu, cunku yazim hatam�z yoktu. Ba�lama ad�m� ba�ar�s�z oldu, ��nk� derleyiciye 'shuffle' fonksiyonunun nerede oldu�unu soylemedik. Ba�lama nedir ve derleyiciye bu fonksiyonu nerede bulaca��n� nas�l s�yleyece�iz?
Ba�lay�c�,ld
, daha once as
ile olu�turulmu�
nesne kodunu al�r ve onu
gcc -o game game.o shuffle.okomutuyla �al��abilir hale getirir. Bu iki nesneyi biraraya getirir ve
game
isimli
cal��abilir dosyay� olu�turur.
Ba�lay�c� shuffle
fonksiyonunu shuffle.o nesnesinden
bulur ve �al���r dosyaya ekler. Nesne dosyalar�n�n g�zel taraf�,
fonksiyonu tekrar kullanmak istedi�imizde, t�m yapmamiz gereken
"deck.h" dosyas�n� eklemek ve shuffle.o
nesne dosyas�n�
yeni �al���r dosyan�n i�ine koymaktan ibarettir.
Bunun gibi kodun yeniden kullan�m� herzaman kar��la��lan bir durumdur.
Hata ay�klama sat�r� olarak kulland���m�z printf
fonksiyonunu
kendimizin yazmamamyzyn sebebi, ba�lay�c� bu fonksiyonun tan�mlamas�n�
#include
<stdlib.h>
dosyas�nda bulur ve (/lib/libc.so.6) C k�t�phanesinde
bulunan nesne koduna ba�lar.
Bu yolla, ba�kas�n�n yazd��� �al��an bir fonksiyonu kullan�p kendi problemlerimizi
��zmekle u�ra�abiliriz. Ba�l�k dosyalar�n�n sadece veri ve fonksiyon tan�mlamalar�n�
i�ermesinin sebebi de budur. Normalde, nesne dosyalar�n� veya k�t�phanelerini
ba�lay�c�n�n �al���r dosyaya koymas� i�in yarat�r�z.
Kodumuzla ilgili bir problem olu�abilir, ��nk� ba�l�k dosyam�za herhangi
bir fonksiyon tan�mlamas� koymadik.
-Wall
anahtari, butun dil yaz�m ikazlar�n�,
kodumuzun do�ru ve m�mk�n oldu�u kadar ta��nabilir oldu�undan emin
olmamiz i�in etkin hale getirir.
Bu anahtar� kullanarak kodumuzu derledi�imizde, �unun gibi bir�ey g�r�r�z:
game.c:9: warning: implicit declaration of function `shuffle'Bu, biraz daha i�imizin oldu�unu bize bildirir.
shuffle
fonksiyonunun nerede oldu�unu derleyiciye bildirmek i�in header dosyas�na
bir sat�r eklememiz gerekiyor, b�ylece derleyici ihtiya� duydu�u b�t�n
denetimleri yapabilir.
Biraz garip g�z�k�yor, ama bu bize tan�mlamalar� ger�ekle�tirim k�sm�ndan ay�rmam�z�
ve fonksiyonumuzu, sadece yeni ba�l�k dosyas�na koyup nesne dosyas�n� birle�tirerek
istedi�imiz yerde kullanmam�z� sa�l�yor.
�u tek sat�r� deck.h dosyas�na koyaca��z.
void shuffle(deck_t *pdeck);Bu b�t�n ikaz mesajlar�n� etkisiz hale getirecek.
Yayg�n olarak kullan�lan ikinci bir derleyici se�ene�i optimizasyondur.
-O#
(i.e. -O2).
Bu derleyiciye hangi seviyede optimizasyon yapaca��m�z� s�yler.
Derleyici, kodun daha h�zl� �al��abilmesi i�in bir �ok h�nere sahiptir.
Bizimki gibi minik bir program i�in fark� anlamayabiliriz, ama b�y�k programlar�n
farkedilir �ekilde h�zl� �al��mas�n� sa�layabilir. Buna heryerde rastlayabilisiniz,
o y�zden ne anlama geldi�ini bilmeniz gerekiyor.
Hepimizin bildi�i gibi, program�m�z�n derlenebiliyor olams�, onun istedi�imiz �ekilde �ali�aca�i anlam�na gelmez. B�t�n numaralar�n bir kez kullan�ld���ndan emin olmak i�in:
game | sort - n | lesskomutunu �al��t�r�p, eksik bir�ey olmad���n� denetleriz. Bir problem varsa ne yapaca��z? Nas�l �rt�n�n alt�na bak�p, hatalar�m�z� bulaca��z? Kodunuzu bir hata ay�klay�c� ile kontrol edebilirsiniz. Bir�ok s�r�m klasik hata ay�klay�c� gdb'yi sa�lar. Komut sat�r� se�enekleri benim gibi sizi de mutsuz ediyorsa, KDE'nin KDbg adresinde sundu�u g�zel bir �ny�z� kullanabilirsiniz. Birbirine �ok benzeyen ba�ka �ny�zler de vardir. Hata ay�klamaya ba�lamak i�in File->Executable se�in ve
game
program�n� bulun.
F5 e bastiginizda ya da menuden Execution->Run se�ti�inizde, ��kt�y�
ayr� bir pencerede g�rmelisiniz. Ne oldu? Pencerede hi�bir�ey g�remediniz mi?
Tela�lanmay�n, KDbg'ye bir�ey olmad�. Problemin kayna��, bizim �al��abilir
dosyaya herhangi bir hata ay�klama bilgisi koymam�� olmam�z, bu y�zden KDbg
i�eride neler oldu�unu s�yleyemez. -g
anahtar� gerekli bilgiyi
nesne dosyalar�na koyar. Nesne dosyalar�n�z� (.o uzant�l�) bu anahtar ile
derlemelisiniz, �imdi komut:
gcc -g -c shuffle.c game.c gcc -g -o game game.o shuffle.ooldu. Bu, �al��abilir dosyan�za gdb ve KDbg neler oldu�unu anlamas�n� sa�layan �engeller koyar. Hata ay�klama �nemli bir yetenektir, bir tanesini iyi bilmeye zaman ay�rman�za de�er. Hata ay�klay�c�lar�n programc�lara yard�m edebilmesini sa�layan �ey kaynak kodda 'Breakpoint' koyabilmesidir. �imdi,
shuffle
fonksiyonunu �a��ran sat�ra bir tane eklemeyi deneyin. K���k bir k�rm�z�
halkan�n sat�r�n yan�nda belirmesi laz�m. �imdi, F5'e bast���n�zda program
o sat�rda duracakt�r. F8 basarak shuffle fonksiyonunun i�erisine
bir ad�m at�n. Hey, �imdi shuffle.c
dosyas�n�n koduna
bak�yoruz! Program�n �al��mas�n� ad�m ad�m takip ederek neler oldu�unu
g�rebiliriz. Farenin i�aret�isini bir yerel de�i�kenin �st�ne getirdi�inizde
hangi de�ere sahip oldu�unu g�rebilirsiniz. �irin. printf
sat�rlar�ndan
daha iyi de�il mi?
Bu makale, sizlere, C programlar�n�n derlenmesi ve hatalar�n�n ay�klanmas�
konusunda k�sa bir tur sundu. Derleyicinin ge�ti�i ad�mlar� ve
bu ad�mlar�n ger�ekle�mesi i�in gcc'ye verilen anahtarlar� inceledik.
Payla��lan k�t�phanelerin ba�lanmas�na bak�p, hata ay�klay�c�lara bir
giri�le bitirdik. Ne yapt���n�z� o�renmek i�in daha �ok �al��maya
gereksinim
var, ama �mit ederim bu makale do�ru ad�mla ba�lanmas�na hizmet eder.
Daha geni� bilgiyi, gcc
, as
ve ld
nin man
ve info
sayfalar�ndan bulabilirsiniz.
En �ok �eyi, kod yazarken o�renirsiniz. Pratik i�in, bu makaledeki kart program�n� kullanarak bir blackjack oyunu yazabilirsiniz. Hata ay�klay�c� kullan�m� o�renmek i�in biraz zaman ay�r�n. KDbg gibi bir GUI ile ba�lamak daha kolayd�r. Her seferinde biraz fonksiyonalite eklerseniz, o�renme i�ini halletmi� olursunuz. Hat�rlatma, program�n�z� daima �al���r halde tutun.
Tam bir oyun yazmak i�in gereksiniminiz olan �eylerden baz�lar�n�n listesi.
|
G�rsely�re sayfalar�n�n bak�m�, LinuxFocus Edit�rleri taraf�ndan yap�lmaktad�r
© Lorne Bailey, FDL LinuxFocus.org Buray� klikleyerek hatalar� rapor edebilir ya da yorumlar�n�z� LinuxFocus'a g�nderebilirsiniz |
�eviri bilgisi:
|
2002-03-04, generated by lfparser version 2.27