yüklenmiş işlev çözümlemesinde özel durumlar – 1

İşlev yüklemesi C++‘ın en sık kullanılan özelliklerinden biri. Derleyicinin bir işlev çağrısı karşılığında yüklenmiş işlevlerden hangisini seçeceğine ingilizcede “function overload resolution” deniyor. Ben bu sürece “yüklenmiş işlevin çözümlenmesi” dedim. Bu süreç C++’ın en karmaşık olduğu alanlardan biri. Bu yazı serisinde amacım bu süreci ayrıntılarıyla anlatmak değil bu sürece ilişkin programcıları yanıltan tipik senaryolara değinmek. Kurallara tam olarak hakim olmayan programcıları şaşırtan durumlardan biri, bazı standart dönüşümler arasında bir seçimin yapılamaması nedeniyle çift anlamlılık hatası (ambiguity) oluşması:

func işlevi içinde f işlevi int türden bir sabitle çağrılıyor. Her iki f işlevi de çağrı için uygun (viable). Dili yeni öğrenmekte olanlar burada unsigned int parametreli f işlevinin çağrılacağını sanabiliyorlar. Ne de olsa unsigned int bir tamsayı türü. Oysa double ise bir gerçek sayı türü. Ama dilin kuralları böyle söylemiyor.

Standartlara göre standart dönüşümler (standard conversions) aşağıdaki gibi kategorize ediliyor ve derecelendiriliyor (ranking) :

tam uyum (exact match) (1. derece yani en yüksek seçilebilirlik)
yükseltme (promotion) (2. derece yani en yüksek ikinci seçilebilirlik)
dönüşüm (conversion) (3. derece yani en düşük seçilebilirlik)

Tam uyum ya da yükseltme kategorilerini bu serinin diğer yazılarında ele alacağım.

dönüşümü, “tam uyum” ya da “yükseltme” olmayan bir standart dönüşüm (conversion). Bir tamsayı türünden başka bir tamsayı türüne dönüşüme ingilizcede “integral conversion” (tamsayı dönüşümü) deniyor. Bunu “integral promotion” (tamsayıya yükseltme) ile karıştırmayalım.

dönüşümü de yine “tam uyum” ya da “yükseltme” olmayan bir standart dönüşüm. (floating point conversion /gerçek sayı türüne dönüşüm). İki dönüşümün de seçicilik açısından derecesi (rank) aynı. Bu durumda çift anlamlılık hatası (ambiguity) oluşuyor. Benzer bir durum aşağıdaki kodda da söz konusu:

f işlevi double türden bir argüman ile çağrılıyor.

dönüşümü yine “tam uyum” ya da “yükseltme olmayan” bir standart dönüşüm. float türünden double türüne dönüşüm söz konusu olsaydı bu “yükseltme” durumu olarak değerlendirilecekti ve “yükseltme”,  yukarıda da açıklandığı gibi daha yüksek dereceye sahip.

dönüşümü de “tam uyum” ya da “yükseltme” olmayan bir standart dönüşüm olduğundan aynı seçilebilirlik derecesine sahip. Yani kodumuzda yine çift anlamlılık hatası var. double türünden int türüne dönüşümün bir veri kaybına neden olması seçicilik açısından bir fark yaratmıyor.
C++ dilini öğrenme sürecinde olanlar, veri kaybına neden olmayan dönüşümlerin veri kaybına neden olan dönüşümlere tercih edileceği beklentisinde olabiliyorlar. “Tam uyum” ve “yükseltme” dışındaki standard dönüşümler arasında (özel bir durum dışında) seçilebilirlik derecesi açısından bir fark yok.

Aşağıdaki standart dönüşümler “tam uyum” ya da “yükseltme” kategorisinde değiller ve aynı dönüşüm derecesine sahipler:

tamsayı türleri arasında yükseltme (promotion) olmayan tüm dönüşümler, örneğin

int altı tam sayı türlerinden yani char, bool ve short türlerinden int türüne dönüşüm ise “yükseltme” olarak ele alınıyor.

Gerçek sayı türüne yapılan ve yükseltme (promotion) olmayan dönüşümler, örneğin

float türünden double türüne dönüşüm ise “yükseltme” olarak ele alınıyor.

Gerçek sayı türlerinden tamsayı türlerine yapılan dönüşümler, örneğin

Geçerli olan adres dönüşümleri, örneğin

bool türüne yapılan dönüşümler, örneğin

“Tam uyum” ve “yükseltme” olmayan iki standart dönüşüm arasında seçicilik kriteri olan bir istisnai durum var:

Yukarıdaki kodda main işlevi içinde f işlevi int türden x nesnesinin adresi ile çağrılıyor. Argüman olan ifadenin türü int *. Her iki f işlevinin parametresine yapılacak dönüşüm de “tam uyum” ya da “yükseltme” kategorisinde değil:

Ancak bu durumda kurallara göre void * türüne yapılan dönüşüm üstünlük sağlıyor. İşlev çağrısında bir çift anlamlılık hatası söz konusu değil. Çağrılan işlev void * parametreli f işlevi olacak.

Necati Ergin

C ve Sistem Programcıları Derneğinde eğitmen olarak çalışıyor.

Bunlar da ilginizi çekebilir

Bir Cevap Yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

Kod Eklemek İçin Okuyun