C programının derleme süreci birkaç aşamadan oluşur: ön işleme (preprocessing), derleme (compilation), montaj (assembling), bağlama (linking). Tarihsel olarak bu yapı, araçlar arasındaki sorumlulukları ayırmayı ve derleme sürecini yönetmeyi kolaylaştırmıştır.
Sorun: Her aşamanın nasıl çalıştığını anlamıyorsanız, "undefined reference" gibi hatalarla, kodun tekrarıyla, makroların yanlış kullanımından kaynaklanan belirsiz hatalarla ve kodun birden fazla dosyaya ölçeklenmesiyle alakalı sorunlarla karşılaşabilirsiniz.
Çözüm: Her aşamanın belirli bir işlevi yerine getirdiğini anlamanız gerekir: Ön işleyici #define, #include ve diğer direktifleri işler, derleyici kaynak C kodunu montaj koduna çevirir, montajcı bunu makine koduna çevirir ve bağlayıcı tüm nesne dosyalarını ve kütüphaneleri son yürütülebilir dosyada birleştirir.
Kod örneği:
Kaynak kod parçası:
#include <stdio.h> #define PI 3.14 int main() { printf("%f\n", PI); return 0; }
Aşamaları açıkça belirterek gcc çağrısı örneği:
gcc -E program.c # Ön işleme gcc -S program.c # Derleme (montaja kadar) gcc -c program.c # Montaj (nesne dosyasına kadar) gcc program.o -o prog # Bağlama (linking)
Ana özellikler:
Derleme aşamasında #include "file.h" direktifi ne işe yarar?
#Include, dosyanın içeriğini derlemeden önce çağrıldığı yere doğrudan ekler. Aynı dosyanın iki kez eklenmesi, nesnelerin birden çok tanımlanmasına veya bağlama sırasında hatalara yol açabilir.
Bir işlevin bir dosyada tanımlanması, başka bir dosyada kullanılmak için yeterli midir?
Hayır, ya başlık dosyasında bir bildirim (prototip) ya da en azından extern-bildirim gereklidir. Aksi takdirde, bağlama sırasında "implicit declaration of function" veya "undefined reference" hataları ile karşılaşabilirsiniz.
Diğer bir dosyadan static olarak tanımlanan değişkenler kullanılabilir mi?
Hayır. static, değişkenin veya işlevin görünürlüğünü mevcut dosya ile sınırlar. Bu, bu tür sembollerin diğer nesne dosyalarında bağlayıcıya görünmediği anlamına gelir.
Bir acemi, iki kaynak dosyasında aynı isimde bir işlevi uygular. Bağlama aşamasında garip bir "multiple definition of function" hatası ortaya çıkar.
Artılar:
Eksiler:
Sadece deklarasyonlar için .h dosyaları, tanımlar için .c dosyaları oluşturulması. Başlık dosyalarını korumak için #ifdef kullanımı. Tüm dosyalar bağlayıcı aracılığıyla nihai programa bağlanır.
Artılar:
Eksiler: