Static assert — ifade (koşul) başarısız olursa derleme aşamasında hata oluşturmak için derleyici tarafından kullanılan bir mekanizmadır. Bu işlev, C++11 ile birlikte şablon programlamayı kolaylaştırmak ve kod kalitesini artırmak için eklenmiştir.
Konuya Giriş.
Static_assert'tan önce, programcılar hata teşhisini daha az okunabilir ve daha az kullanışlı bir şekilde yaparak, negatif boyuta sahip bir diziyle (örneğin char arr[condition?1:-1];) hileler kullanıyordu. Bu da anlamlı hata bildirimi ile derleme zamanı hatalarının açık bir şekilde beyanda bulunma ihtiyacını doğurdu.
Problemin Tanımı.
Şablon programlamada, uygun olmayan tür veya parametrelere sahip bir nesnenin oluşturulmasını engelleme gibi erken teşhis gereksinimleri sıkça ortaya çıkmaktadır. Statik kontrol olmadan, bu tür hatalar yalnızca nihai kod derlenmesi aşamasında (bazen ani ve açıklanması zor bir hata olarak) görünüyordu.
Çözüm.
static_assert anahtar kelimesi bir boolean ifade ve bir mesaj dizesi alır. Eğer ifade yanlışa eşitse, derleme bir hata ile biter ve mesajı görüntüler.
Kod örneği:
static_assert(sizeof(int) >= 4, "int en az 4 byte olmalıdır"); template<typename T> void foo(const T& obj) { static_assert(std::is_copy_constructible<T>::value, "T kopya ile oluşturulabilir olmalıdır"); }
Ana özellikler:
İkinci argüman olmadan static_assert kullanılabilir mi?
Evet, C++17 itibarıyla ikinci argüman isteğe bağlıdır:
static_assert(sizeof(double) == 8); // mesaj varsayılan olarak olacaktır
Şablon parametrelerine bağlı koşullar varsa static_assert ifadeleri çalışır mı ancak şablon örneklendirilmezse?
Hayır, static_assert yalnızca örneklendirme noktasına gelindiğinde çalışır; bu, yalnızca kullanılan şablonlar için kontrollerin uygulanmasına olanak tanır.
Static_assert içinde çalışma zamanı ifadeleri (run-time) kullanılabilir mi?
Hayır, ifade derleme aşamasında hesaplanabilir olmalıdır (constexpr). Eğer ifade constexpr değilse — derleme hatası oluşur.
Koda, yalnızca çalışma zamanında hesaplanan bir ifade ile static_assert kullanıldı (örneğin, dosya boyutunu okuma ile ilgili), bu da sistemde karmaşık bir derleme hatasına yol açtı.
Artılar:
Eksiler:
Matrix şablonunun yalnızca Plain Old Data (POD) türleri ile oluşturulabileceğini garanti altına almak gerekiyor, karmaşık yapıların dışlanması.
template<typename T> class Matrix { static_assert(std::is_pod<T>::value, "Matrix yalnızca POD türleri için örneklendirilebilir"); // ... };
Artılar:
Eksiler: