deniz.in

Piyasalar

Hava durumu

Hava durumu yükleniyor

· kaynak Hacker News – Front Page (hnrss.org)

C++26 sertleştirme (hardening), sınır dışı standart kütüphane çağrılarını contract ihlaline dönüştürüyor

C++26, sertleştirilmiş standart kütüphane uygulamalarının sınır dışı erişim ve diğer önkoşul ihlallerini sonlandıran contract ihlalleri olarak bildirmesine olanak tanıyor; GCC, Clang ve MSVC bunun için birer anahtar sunuyor.

C++26 sertleştirme (hardening), sınır dışı standart kütüphane çağrılarını contract ihlaline dönüştürüyor

C++26 neleri değiştiriyor

std::vector kullanan herkes v[i] ile v.at(i) arasındaki farkı bilir: ilki sınır kontrolü yapmaz ve indeks aralık dışında olduğunda tanımsız davranışa yol açar, ikincisi ise std::out_of_range fırlatır. C++26 üçüncü bir olası sonuç ekliyor. Standart artık "sertleştirilmiş uygulama" (hardened implementation) kavramını tanımlıyor ve vector::operator[]'e aralık dışı bir indeks geçirildiğinde sertleştirilmiş bir uygulama, tanımsız davranış yerine bir contract ihlali üretiyor; bu, yakın zamanda Hacker News'in ön sayfasına çıkan bir C++ Stories makalesine göre yapılıyor. Belirli bir kütüphane uygulamasının sertleştirilmiş olup olmadığı ve modun nasıl açılacağı ise implementation-defined olarak bırakılmış.

Fırlatmıyor, sonlandırıyor

Mekanizma bilinçli olarak at()'in bir kopyası değil. Makalenin açıkladığı gibi, sertleştirme bir programlama hatasını tespit eder ve çalışmayı durdurur; kurtarılabilir bir hata yolu sunmaz. İstisnalar pratikte kapatılması zor şeylerdir ve zaten at() ile operator[] arayüz ve performans beklentileri açısından farklıdır.

Sertleştirme, C++26'ya kabul edilen Contracts özelliği üzerinden ifade ediliyor. Sıradan contract doğrulamaları ignore, observe, enforce veya quick-enforce semantiğiyle çalışabilir, ancak sertleştirilmiş kütüphane önkoşulları daha kısıtlayıcı: sonlandırıcı (terminating) bir semantik kullanmak zorundadırlar; böylece bir program başarısız olan bir kontrolü gözlemleyip sertleştirmenin önlemesi amaçlanan tanımsız davranışa düşemez. Bu garanti P3878 önerisinden geliyor. Uygulamaların kontrolleri yapmak için gerçek pre, post veya contract_assert dil sözdizimini kullanması gerekmiyor ve kontroller hem sabit ifadelerde hem de çalışma zamanında geçerli.

Hangi işlemler kapsanıyor

Özelliğin büyük bölümü P3471 önerisinden geliyor; P3697 ise kapsamı basic_stacktrace, shared_ptr<T[N]>, view_interface, counted_iterator ve common_iterator gibi türlere genişletiyor. Bir önkoşul, üç koşul sağlandığında sertleştirilmiş önkoşul haline gelir: ihlali sınır dışı erişim veya başlatılmamış bellek okuma gibi bir bellek güvenliği sorunu yaratıyor, çağrı noktası kontrolü yapmak için gereken tüm verilere sahip ve kontrol nispeten düşük ek yükle sabit zamanda çalışıyor.

Ortaya çıkan kapsam — cppreference'ın sertleştirilmiş önkoşullara sahip işlevler tablosunda özetlediği gibi — operator[], front(), back(), pop_front() ve pop_back() için sıra container'larını (array, vector, inplace_vector, deque, list, forward_list); span, mdspan ve view_interface gibi view'leri; iterator adaptor'larını; remove_prefix() ve remove_suffix() dahil basic_string ve basic_string_view'ı; bitset, optional ve expected'ı; shared_ptr<T[N]>'yi; ve valarray'ı kapsıyor.

Nasıl açılır

Üreticiler C++26 işini bitirene kadar makale, C++26'nın fiilen tek bir ortak, iyi tanımlanmış kural setinde birleştirdiği mevcut üreticiye özel anahtarlara işaret ediyor:

  • GCC ve libstdc++: _GLIBCXX_ASSERTIONS; daha geniş kapsamlı -fhardened seçeneği tarafından da otomatik olarak etkinleştiriliyor.
  • Clang ve libc++: _LIBCPP_HARDENING_MODE; NONE, FAST, EXTENSIVE ve DEBUG seviyeleriyle.
  • MSVC STL: _MSVC_STL_HARDENING=1, ayrıca _MSVC_STL_HARDENING_VECTOR ve _MSVC_STL_HARDENING_OPTIONAL gibi türe özel makrolar.

Makaledeki bir gösterim, GCC 16.1'in kutudan çıktığı gibi kötü bir indeksi yakaladığını gösteriyor: optimize edilmemiş bir derlemede libstdc++ şu anda _GLIBCXX_ASSERTIONS'ı varsayılan olarak etkinleştiriyor, dolayısıyla üç elemanlı bir vector'ün sonunun çok ötesine yazmak bir assertion hatası ve bir SIGSEGV üretiyor. Ancak -O2 ile derlendiğinde assertion'lar yeniden kapanıyor ve geriye düz bir segfault kalıyor. Makale, Ağustos 2026 itibarıyla üreticilerin özelliği hâlâ tamamlıyor olduğu konusunda uyarıyor; yani bu anahtarlar henüz P3471, P3697 ve P3878'in tam uygulamalarını temsil etmeyebilir.

Neden önemli

Sınır dışı container erişimi, C++ kod tabanlarında bellek bozulmasının en yaygın kaynaklarından biridir ve günümüzdeki hafifletmeler üreticiye özel makro kümelerine dağılmış durumda. C++26 bu geçici çözümleri, sonlandırıcı semantiğe sahip tek bir tanımlanmış modele katıyor ve sessiz tanımsız davranış yerine öngörülebilir, teşhis edilebilir bir hata veriyor — bu hem hata ayıklama hem de sevkiyat edilen yazılımın saldırı yüzeyini daraltma açısından değerli.

Bu, C++'ı tamamen bellek güvenli hale getirmiyor: ham işaretçi aritmetiği ve kapsanan listenin dışındaki kontrolsüz işlemler eskisi kadar tehlikeli kalıyor ve kontroller bir runtime maliyeti taşıyor; bu maliyet sabit zaman gereksinimiyle küçük tutuluyor. Ancak hâlâ çok büyük miktarda kritik altyapıyı çalıştıran bir dil için, kütüphane düzeyindeki bütün bir hata sınıfını anında, iyi tanımlanmış başarısızlıklara dönüştürmek pratik ve uzun zamandır beklenen bir iyileştirme.

  • #cpp
  • #cpp26
  • #memory-safety
  • #standard-library
  • #compilers