Bu muhtemelen istediğinizden daha ayrıntılı bir cevaptır, ancak bence iyi bir açıklama haklı.
C ve C ++ 'da, bir kaynak dosya bir çeviri birimi olarak tanımlanır . Kural olarak, başlık dosyaları işlev bildirimlerini, tür tanımlarını ve sınıf tanımlarını içerir. Gerçek işlev uygulamaları çeviri birimlerinde, yani .cpp dosyalarında bulunur.
Bunun arkasındaki fikir, işlevlerin ve sınıf / yapı üyesi işlevlerinin bir kez derlenip birleştirilmesidir, daha sonra diğer işlevler, bu kodu tek bir yerden yinelemeden çağırabilir. Fonksiyonlarınız dolaylı olarak "extern" olarak ilan edilir.
/* Function declaration, usually found in headers. */
/* Implicitly 'extern', i.e the symbol is visible everywhere, not just locally.*/
int add(int, int);
/* function body, or function definition. */
int add(int a, int b)
{
return a + b;
}
Bir işlevin çeviri birimi için yerel olmasını istiyorsanız, işlevi 'statik' olarak tanımlarsınız. Ne anlama geliyor? Bu, extern işlevlerine sahip kaynak dosyaları eklerseniz, derleyici aynı uygulamaya birden fazla kez rastladığından yeniden tanımlama hataları alırsınız. Böylece, tüm çeviri birimlerinizin işlev bildirimini görmesini istiyorsunuz, ancak işlev gövdesini görmüyorsunuz .
Peki sonunda bunların hepsi nasıl eziliyor? Bağlayıcının işi budur. Bir bağlayıcı, birleştirici aşaması tarafından oluşturulan tüm nesne dosyalarını okur ve sembolleri çözer. Daha önce söylediğim gibi, bir sembol sadece bir isimdir. Örneğin, bir değişkenin veya işlevin adı. İşlevleri çağıran veya tür bildiren çeviri birimleri bu işlevler veya türler için uygulamayı bilmiyorsa, bu sembollerin çözülmediği söylenir. Bağlayıcı, tanımlanmamış sembolü tutan çeviri birimini uygulamayı içeren çeviri birimiyle birleştirerek çözülmemiş sembolü çözer. Uf. Bu, kodunuzda uygulanmış veya ek bir kütüphane tarafından sağlanmış olsun, harici olarak görünen tüm semboller için geçerlidir. Bir kütüphane gerçekten sadece yeniden kullanılabilir kodlu bir arşivdir.
İki önemli istisna vardır. İlk olarak, küçük bir fonksiyonunuz varsa, bunu satır içinde yapabilirsiniz. Bu, üretilen makine kodunun harici bir işlev çağrısı üretmediği, ancak tam anlamıyla yerinde birleştirildiği anlamına gelir. Genellikle küçük olduklarından, havai boyut önemli değildir. Onların çalışma biçiminde statik olduklarını hayal edebilirsiniz. Böylece satır içi işlevlerin başlıklara uygulanması güvenlidir. Bir sınıf veya yapı tanımı içindeki işlev uygulamaları da derleyici tarafından otomatik olarak satır içine alınır.
Diğer istisna şablonlardır. Derleyicinin örnek oluştururken tüm şablon türü tanımını görmesi gerektiğinden, uygulamayı bağımsız işlevlerde veya normal sınıflarda olduğu gibi tanımdan ayırmak mümkün değildir. Belki şu anda bu mümkün, ancak "export" anahtar kelimesi için yaygın derleyici desteği almak uzun, uzun sürdü. Dolayısıyla, 'dışa aktarma' desteği olmadan çeviri birimleri, satır içi işlevlerin nasıl çalıştığına benzer şekilde, örneklenmiş şablonlanmış türlerin ve işlevlerin kendi yerel kopyalarını alır. 'İhracat' desteği ile durum böyle değil.
İki istisna dışında, bazı kullanıcılar satır içi işlevlerin, geçici işlevlerin ve geçici türlerin uygulamalarını .cpp dosyalarına koymayı "daha hoş" bulurlar ve sonra # .cpp dosyasını ekler. Bunun bir başlık veya kaynak dosya olması gerçekten önemli değildir; önişlemci umursamaz ve sadece bir sözleşmedir.
C ++ kodundan (birkaç dosya) ve son yürütülebilir dosyaya kadar tüm sürecin hızlı bir özeti:
- Önişlemci bir '#' ile başlayan tüm direktifleri ayrıştırır, hangi çalıştırılır. #İnclude yönergesi, dahil edilen dosyayı daha düşük bir değerle birleştirir. Ayrıca makro değiştirme ve belirteç yapıştırma yapar.
- Gerçek derleyici , önişlemci aşamasından sonra ara metin dosyasında çalışır ve derleyici kodunu yayar.
- Montajcı montaj dosyası ve yayar makine koduna çalışır, bu genellikle bir denir nesne dosyası ve söz konusu ameliyat sisteminin ikili yürütülebilir biçimine uygundur. Örneğin, Windows PE'yi (taşınabilir yürütülebilir biçim) kullanırken Linux GNU uzantılarıyla birlikte Unix System V ELF biçimini kullanır. Bu aşamada, semboller hala tanımsız olarak işaretlenir.
- Son olarak, bağlayıcı çalıştırılır. Önceki tüm aşamalar sırayla her çeviri biriminde yürütülmüştür. Ancak, bağlayıcı aşaması, birleştirici tarafından oluşturulan tüm oluşturulan nesne dosyalarında çalışır. Bağlayıcı, sembolleri çözer ve hedef platforma ve ikili formata bağlı olan bölümler ve segmentler oluşturmak gibi bir sürü sihir yapar. Programcıların bunu genel olarak bilmeleri gerekmez, ancak bazı durumlarda kesinlikle yardımcı olur.
Yine, bu kesinlikle istediğinizden daha fazlaydı, ama umarım incelikli ayrıntılar daha büyük resmi görmenize yardımcı olur.