C dilinin bazı özellikleri işe yarayan hackler olarak başladı.
Ana ve değişken uzunluklu bağımsız değişken listeleri için birden çok imza bu özelliklerden biridir.
Programcılar, bir işleve fazladan argümanlar iletebildiklerini ve verilen derleyicilerde kötü bir şey olmadığını fark ettiler.
Çağrı kuralları şu şekildeyse durum budur:
- Çağıran işlev argümanları temizler.
- En soldaki argümanlar yığının tepesine veya yığın çerçevesinin tabanına daha yakındır, böylece sahte argümanlar adreslemeyi geçersiz kılmaz.
Bu kurallara uyan bir arama kuralları kümesi, çağıranın bağımsız değişkenleri açtığı ve sağdan sola itildiği yığın tabanlı parametre geçişidir:
;; pseudo-assembly-language
;; main(argc, argv, envp); call
push envp ;; rightmost argument
push argv ;;
push argc ;; leftmost argument ends up on top of stack
call main
pop ;; caller cleans up
pop
pop
Bu tür çağrı kurallarının söz konusu olduğu derleyicilerde, iki tür mainveya hatta ek türlerin desteklenmesi için özel bir şey yapılmasına gerek yoktur . mainargümansız bir fonksiyon olabilir, bu durumda yığına itilen öğelerden habersizdir. İki bağımsız değişkenlerin bir fonksiyonu varsa, o zaman bulur argcve argviki üstteki yığın öğeler olarak. Ortam işaretçisine (ortak bir uzantı) sahip platforma özgü üç bağımsız değişkense, bu da işe yarayacaktır: üçüncü bağımsız değişkeni yığının tepesinden üçüncü öğe olarak bulacaktır.
Ve böylece tüm durumlarda sabit bir çağrı çalışır ve programa tek bir sabit başlatma modülünün bağlanmasına izin verir. Bu modül, şuna benzer bir fonksiyon olarak C'de yazılabilir:
extern int main(int argc, char **argv, char **envp);
void __start(void)
{
exit(main(argc_from_somewhere, argv_from_somewhere, envp_from_somewhere));
}
Diğer bir deyişle, bu başlangıç modülü her zaman üç argümanlı main çağırır. Main hiçbir argüman almazsa veya sadece int, char **, çağıran kurallar nedeniyle hiçbir argüman almadığı gibi iyi çalışır.
Programınızda bu tür bir şey yapacak olsaydınız, bu taşınamaz ve ISO C tarafından tanımlanmamış bir davranış olarak kabul edilir: bir işlevi bir şekilde bildirmek ve çağırmak ve başka bir şekilde tanımlamak. Ancak bir derleyicinin başlangıç hilesi taşınabilir olmak zorunda değildir; taşınabilir program kurallarına göre yönlendirilmez.
Ancak, çağırma kurallarının bu şekilde çalışamayacak şekilde olduğunu varsayalım. Bu durumda, derleyicinin mainözel olarak işlem yapması gerekir . mainFonksiyonu derlediğini fark ettiğinde , örneğin üç argüman çağrısıyla uyumlu bir kod üretebilir.
Yani şunu yazıyorsun:
int main(void)
{
}
Ancak derleyici onu gördüğünde, esasen bir kod dönüşümü gerçekleştirir, böylece derlediği işlev daha çok şuna benzer:
int main(int __argc_ignore, char **__argv_ignore, char **__envp_ignore)
{
}
isimlerin __argc_ignoretam anlamıyla var olmaması dışında . Kapsamınıza bu tür isimler girilmez ve kullanılmayan argümanlar hakkında herhangi bir uyarı olmaz. Kod dönüşümü, derleyicinin kodu, üç bağımsız değişkeni temizlemesi gerektiğini bilen doğru bağlantıyla yayınlamasına neden olur.
Başka bir uygulama stratejisi, derleyicinin veya belki de bağlayıcının __startişlevi (veya her ne denirse) özel olarak oluşturması veya en azından önceden derlenmiş birkaç alternatiften birini seçmesidir. Desteklenen biçimlerden hangisinin kullanıldığına ilişkin bilgi nesne dosyasında saklanabilir main. Bağlayıcı bu bilgiye bakabilir mainve programın tanımıyla uyumlu bir çağrı içeren başlangıç modülünün doğru sürümünü seçebilir . C uygulamaları genellikle yalnızca az sayıda desteklenen biçime sahiptir, mainbu nedenle bu yaklaşım uygulanabilirdir.
C99 dili için derleyiciler main, bir dereceye kadar, işlev bir returnifade olmadan sona ererse , davranışın return 0yürütülmüş gibi görünmesini sağlamak için her zaman özel olarak ele almak zorundadır . Bu yine bir kod dönüşümü ile ele alınabilir. Derleyici, çağrılan bir işlevin mainderlendiğini fark eder . Daha sonra vücudun sonuna ulaşılabilecek durumda olup olmadığını kontrol eder. Eğer öyleyse, birreturn 0;
mainTek bir programdaC(veya gerçekten, böyle bir yapıya sahip hemen hemen her dilde) yalnızca bir yönteme sahip olabilirsiniz .