Haftalık C++ 30 – Nitelikler (“attributes”)

Rainbow, Roadway, Beautiful, Landscape, Country Road

Merhaba arkadaşlar, en son hortlattığım yazımda da bahsettiğim üzere, C++ 11 ile ilgili değinmediğim bir takım kabiliyetlere değinmeye başlıyorum.

nitelikler (“attributes”)

Bakacağımız özelliklerden ilki nitelik (“attribute”). Bu kabiliyetin temel amacı, kaynak kod içerisine opsiyonel ya da araca özel bir takım bilgiler gömmektir diyebiliriz. Java ve C# geliştiricileri “annotation” dersem, eminim ne demek istediğimi anlarsınız. Burada amaç, kod yapıları içerisine ek bilgi atamak olabileceği gibi, derleyici veya benzeri araçlar için de bilgi olabilir (derleyiciye iletilecek not olarak da düşünülebilir). Burada temel kriter, bu tarz tanımlamaların, programın genel amacını değiştirmemesidir.

Bunlara benzer bir takım kabiliyetler daha önce “#pragma, __attribute__, __declspec” gibi anahtar kelimler ile de sağlanıyordu, fakat bunun bir standardı yoktu (bunlara ilişkin de yazımın sonuna bir kaç bağlantı bırakacağım. Meraklı okuyucularım, ziyaret edebilirler). C++ 11 ile bu tarz kullanımlar için, standart bir yaklaşım getirildi. Bu sayede, C++ içerisinde bulunan bir çok yapı (ör. değişken, fonksiyon, vb.) için bu tanımlamaları artık yapabiliyoruz.

Bunları tanımlarken genelde hemen önce tanımı yapılan yapıya ilişkin yapılır. Hemen örnekler ile bakalım:

Niteliklerin aşağıda verilen şekilde tanımlanmaktadır:

[[namespacename::attributename]] 

Burada namespacename ve ::, opsiyoneldir. Bu sebeple, genelde ön tanımlı nitelikler yukarıdaki örnekteki gibi [[noreturn]] ve [[carries_dependency]] şeklinde tanımlanır. Burada, namespacename ne için kullanılacak peki diye aklınıza bir soru gelebilir. Bu da aslında, araç geliştiriciler için, kendi niteliklerini tanımlama için standart bir format sunmaktır.

Şimdi, muhtemelen sizin aklınızda iki temel soru var. Bir, yukarıdaki nitelikler ne anlama geliyor, iki daha başka hangi nitelikler var. Güzel. Tek tek, bu sorulara bir göz atalım:

Birinci sorunuza bakacak olursak:

  • [[noreturn]]: derleyiciye bu fonksiyonun herhangi bir dönüşü olmayacağını bildirmek için eklenir (ismi de sanki biraz ip ucu veriyor ne dersiniz 🙂 ). Bu hem geliştiriciyi de bir şekilde uyarmak için. Bu nerede kullanılabilir diye soracak olursanız. __Exit, exit, quick_exit, terminate ve std::rethrow_exception fonksiyonları bu şekilde işaretlenmiştir. Daha detaylı bilgi için https://en.cppreference.com/w/c/language/_Noreturn sayfasına göz atabilirsiniz.
  • [[carries_dependency]]: bu da yine derleyici için, bellek operasyonların yönelik ekstra optimizasyonlar yapabilmesine yönelik bir not olarak düşünülebilir. Bunun açıkçası, şu soruya verilen cevap güzel açıklıyor https://stackoverflow.com/questions/6411270/what-does-the-carries-dependency-attribute-mean/6411703#6411703. Bir çok sayfa da, nedense buraya sizleri yönlendiriyor 🙂

İkinci sorumuza gelecek olursak:

  • C++ 11 ile sadece yukarıdaki iki tanesi geliyor,
  • C++ 14 ile birlikte [[deprecated]] ve[[deprecated("reason")]] geliyor. İsminden de anlaşılacağı üzere, ilgili kod yapısının artık kullanılmaması gerektiğini bir şekilde ifade ettirmek için ekleniyor. Bu da genelde derleyici uyarısı olarak karşımıza çıkıyor. Ör.
  • C++ 17’de ise [[fallthrough]],[[nodiscard]] ve [[maybe_unused]]gibi üç adet standard nitelik sunulmaya başlandı. Bunlardan ilki switch ifadelerinde özellikle break konulmadığı durumlarda uyarı almamak için kullanılıyor. Bunun sonuna noktalı virgül de koymalısınız. İkinci, bir fonksiyonun dönüş değerinin özellikle göz ardı edilmemesini ifade etmek için kullanılıyor ki, bu durumda uyarı veriliyor. Sonuncusu ise, kullanılmayan öğeler için derleyicinin uyarı vermemesini sağlamak için kullanılıyor. Hemen örnekler ile bunlara bakalım:
  • C++ 20 ile [[likely]],[[unlikely]]nitelikleri sunulacak. Bunlar da derleyiciye optimizasyonu yapabilmesi için, neyin kullanılıp/kullanılmayacağına ilişkin ipuçu vermeyi hedefliyor.

Derleyiciler tarafından sunular niteliklere ilişkin sayfaları aşağıdaki kaynaklara ekliyorum 😉

Kaynaklar:

Bir cevap yazın

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.