consteval, C++20'de tanıtılan bir etiket olup, anlık işlevler oluşturarak derleme zamanı sabitleri üretmeyi zorunlu kılar. constexpr'ın aksine, argümanlar sabit ifadeler olmadığında çalışma zamanı yürütülmesine izin veren consteval, her çağrının sabit değerlendirilen bir bağlamda gerçekleşmesini zorunlu kılar. Bu kural, olası çalışma zamanı mantığını katı derleme zamanı gereksinimlerine dönüştürerek, sessiz çalışma zamanı geri dönüş mekanizmalarını anlık derleme hatalarına çevirir.
Tarihsel olarak, constexpr'ın iki yönlü doğası, geliştiricilerin sıfır maliyetli derleme zamanı değerlendirmesi varsaymalarına neden olan ince hatalara yol açtı ancak istemeden çalışma zamanı kod üretimini tetikledi. consteval, tamamen çalışma zamanı yolunu ortadan kaldırarak bu belirsizliği ortadan kaldırır ve ihlallerin kötü biçimlendirilmiş programlar olarak ortaya çıkmasını sağlar; performans düşüşleri veya güvenlik açıkları yaratmaz.
Bir gömülü sistemler ekibi, firmware görüntülerinde kötüye kullanımı önlemek için kriptografik tohum değerlerinin tamamen derleme zamanında hesaplanmasını sağlamalıydı. Başlangıçta, derleyicinin tüm çağrıları inşa sürecinde değerlendireceğini düşünüp constexpr hash işlevlerini kullandılar.
Çözüm 1: Statik doğrulama bekçeleri
Mühendisler, her hash çağrısını static_assert ile sarmaladılar; bu durumun çalışma zamanı değerlendirme girişimlerini durduracağını düşünüyorlardı. Birim testlerde etkili olmasına rağmen, bu yaklaşım, başka bir geliştiricinin hash işlevine bir çalışma zamanı yapılandırma bayrağı geçmesiyle entegrasyonda başarısız oldu. Derleyici, hashing algoritması için makine kodunu sessizce üretti ve ikili boyutu on iki kilobayt arttı; gerçek zamanlı kısıtlamaları ihlal etti. Statik doğrulamalar yalnızca belirli çağrı noktalarını doğruladı, tüm olası çağrıları değil.
Çözüm 2: Şablon metaprogramlama Algoritmayı şablon metaprogramlama ile struct özel durumları ve özyinelemeli derleme zamanı özyinelemesi kullanarak değiştirmeyi düşündüler. Bu yaklaşım derleme zamanı değerlendirmesini garanti edecekti ancak küçük tür uyumsuzlukları için beş yüz satırı aşan anlaşılmaz hata mesajları üretti. Hata ayıklama zor hale geldi ve derleme süreleri, aşırı şablon örnekleme derinliği nedeniyle yüzdesel olarak dört yüz arttı.
Çözüm 3: consteval zorlaması (Seçilen) İşlevi consteval'e geçirmek, geliştiricilerin çalışma zamanı çağrısı denemesi yaptıklarında anlık tanılama sağladı. Derleyici, herhangi bir sabit olmayan argümanı katı bir hata olarak değerlendirdi ve işlevin asla çalışma zamanı talimatları üretmesini engelledi. Ekip, söz dizimini okunaklı tutarken yürütme zamanlaması hakkında mutlak garantiler sağladığı için bu çözümü seçti; şablon kabarıklarından kaçındı.
Sonuç, çalışma zamanı tohum üretimi riskini tamamen ortadan kaldırdı. İkili boyut beklenen sınırlara döndü ve yapılandırma hataları, geç aşama entegrasyon testleri sırasında değil, birkaç saniye içinde yakalandı.
Neden consteval işlevleri constexpr işlevlerini çağırabilir, ancak tam tersi kesin bağlamsal kısıtlamalar gerektirir? Bir consteval işlevi yalnızca sabit değerlendirilen bağlamlarda çalışır, dolayısıyla bir constexpr işlevini çağırmak her zaman güvenlidir çünkü derleme zamanı sözleşmesi korunur. Ancak bir constexpr işlevi çalışma zamanında yürütülebilir, bu nedenle belirli çağrı noktası kendisi açıkça sabit değerlendirilen bir bağlamda değilse, bir consteval işlevini çağırmak mümkün değildir. Bir constexpr işlevinin çalışma zamanı dalında consteval çağrılması, consteval'in anlık değerlendirme talep ettiği için kötü biçimlendirilmiş bir program oluşturur.
Neden consteval işlevinin adresini almak dil spesifikasyonunu ihlal eder?
consteval işlevleri bir çalışma zamanı adresine veya çağrılabilir bir gövdeye sahip değildir; yalnızca derleme zamanı hesaplama ilkelere olarak var olurlar. Sonuç olarak, &func ifadesi, referans alacak bellek konumu olmadığı için kötü biçimlendirilmiştir. Buna karşılık, constexpr işlevleri hem derleme zamanı hesaplayıcıları hem de çalışma zamanı yürütülebilir kod olarak çift kimliklerini korur; dolayısıyla adreslerinin alınmasına ve işlev işaretçilerine veya std::function nesnelerine depolanmasına izin verir.
consteval, tanımsız davranışı constexpr'dan farklı nasıl ele alır ve bu, güvenlik açısından kritik kodlar için neden önemlidir?**
Bir consteval işlevinin içinde, tanımsız davranış, programın derleme sırasında anında kötü biçimlendirilmesine neden olur ve savunmasız çalışma zamanı makine kodunun üretilmesini engeller. constexpr değerlendirmesi, sabit katlama sırasında bazı tanımsız davranışları tespit eder, ancak çalışma zamanı değerlendirilirse tanımsız anlamlar taşıyan kodun yürütülmesine izin verir. consteval'in katı modeli, doğrulanan kod yollarının tanımsız davranış istismarlarından uzak olmasını garanti eder, agresif derleyici optimizasyonlarına olanak tanır ve güvenlik açısından hassas hesaplamaların üretim ortamlarında tampon taşmaları veya tam sayı sarılmaları ile karşılaşmamasını sağlar.