Haberler:

Eposta uyarılarını yanıtlamayınız ( ! ) https://bit.ly/2J7yi0d

Ana Menü

_cplusplus

Başlatan mr.engineer, 20 Nisan 2021, 10:02:39

mr.engineer

example.h

#ifdef __cplusplus
extern "C" {
#endif
////
////

#ifdef __cplusplus
} // extern "C"
#endif


Yukarudaki preprocessor işlemini anladığım kadarıyla hem C hem de C++ kaynak dosyaları içeren projelerde kullanıyoruz. Şimdi ben yukarıdaki example.h başlık dosyasını hem bir .c hem de .cpp dosyasında kullanabiliyorum.

Bu başlık dosyasında zaten sadece fonksiyon bildirimleri ve typedefler falan var. Bu başlık dosyasını .c veya .cpp dosyasına ekleyip derleme yaptığımızda bu başlık dosyasındaki fonksiyonlar C'de derlenecek ve c++'da da kullanabileceğiz değil mi?

Bu başlık dosyasındaki fonksiyonlar .c uzantılı dosyada tanımlı olmak zorunda, doğru mu? Bu fonksiyonlar .c de yazılmasına rağmen c++ semantiğine uygun olmak zorunda mı?

Bir de yukarıdaki #ifdef _cplusplus kısmının çalışması için _cplusplus define edilmesi gerekmiyor mu? Bu nerede define ediliyor?


Tagli

_cplusplus tanımlaması C++ derleyicisi tarafından otomatik yapılır. C ile derlenirken bu tanımlama mevcut değildir.

extern "C" bloğu, C++ derleyicisinin fonksiyon isimlerine (ve belki de değişken isimlerine de, emin değilim) normalde uyguladığı name mangling işlemi uygulamasını engeller. Bu işlem, isimlere derleyicinin kafasına göre ekler koyup isimleri değiştirmesidir. C bunu yapmaz. Bu sebeple C ve C++ derleyicilerinin isim beklentileri farklıdır.

extern "C" bloğu genelde C++ üzerinden çağrılacak fakat C ile derlenmiş (yani bir .c dosyasında tanımlanmış) fonksiyonları içeren header dosyalarında olur. Bu ifade ile C++ derleyicisi, header'da geçen isimleri olduğu gibi kabul etmesi gerektiğini bilebilir. C derleyicisinin oluşturduğu binary objelerde isimler zaten değiştirilmemiş hali ile bulunur. Böylece iki taraftaki isimler de birbirine uyar, bağlayıcı (linker) da bunları birbirine bağlayabilir.
Gökçe Tağlıoğlu

mr.engineer

Teşekkürler.
Hocam böyle bir işlemde iki derleyici birden mi çalışıyor her zaman?

Tagli

İşlemci açısından bir şey fark etmez. Yani işlemci derleyicileri görmez, kendisine yüklenen kodu çalıştırır.

Ama evet, bu tür bir proje iki farklı derleyici ile derlenir. Bağlayıcı farklı dillerde oluşturulmuş binary objelerini birbirine bağlayabilir, tabi kurallar uyuşuyorsa.

Genelde C dili için kurallar daha katı, dil de zaten daha basit. Bu yüzden üretici firmadan bağımsız olarak C derleyicileri ile üretilmiş kodu çağırırken pek sıkıntı olmuyor. Farklı derleyiciler ile üretilmiş C objeleri de birbirine bağlanabiliyor sanırım. Başka dillerden C fonksiyonlarını çağırmak da pek sıkıntı olmuyor.

C++ için durum daha karmaşık. Name mangling yöntemi derleyiciden derleyiciye değişebiliyor. Farklı firmaların C++ derleyicilerinin ürettiği binary objeler birbirine bağlanamayabilir.

Aynı firmanın C ve C++ derleyicileri ile çalışıldığında pek sorun olmuyor. Örneğin GCC'nin C ve C++ derleyicileri birbirlerinden kod çağırabiliyor. Örnek vermek gerekirse, ben STM32 projelerimi STM32CubeIDE'de boş C++ projesi olarak oluşturuyorum. Bu projeye eklediğim kaynak dosyaları uzantılarına göre C veya C++ derleyicisi ile derleniyor. Proje ayarlarında iki dil için ayrı ayar menüleri görüyorum. Projemde FreeRTOS kullanıyorum ki bu zaten C ile yazılmış. Ama benim kod C++ kodu. Bazen daha önce yazdığım ama C++'a geçirmediğim eski C kodlarını da doğrudan projeye ekleyebiliyorum. Ama tabi bu C kodlarının header dosyalarında extern "C" bloğu olması lazım.
Gökçe Tağlıoğlu