Cake – C23 और आगे (2023)

Cake C23 frontend के माध्यम से C में Rust-जैसी ownership और memory-safety checks जोड़ने के प्रयासों ने रुचि और संदेह दोनों पैदा किए हैं। समर्थक compile-time resource lifetime tracking (जैसे `malloc`/`free`, `fopen`/`fclose`) को मौजूदा code पर परत की तरह जोड़ने और GCC/Clang के लिए उसे compile away करने में मूल्य देखते हैं, जबकि आलोचक सवाल करते हैं कि ये annotations कितनी अच्छी तरह compose होती हैं, बड़ी libraries को retrofit करना कितना व्यावहारिक है, और क्या partial, opt-in safety इतनी complexity के लायक है। चर्चा अक्सर इस approach की तुलना Rust, custom allocators, और mempools जैसे विकल्पों से करती है, और व्यापक प्रश्न उठाती है कि क्या C को धीरे-धीरे harden किया जाना चाहिए या inherently memory-safe languages से बदला जाना चाहिए।

Cake में स्वामित्व मॉडल

  • Cake C23 में _Owner, _View, आदि क्वालिफ़ायर्स और flow analysis जोड़ता है ताकि resource lifetime की जाँच की जा सके (जैसे, FILE * owner), और मुख्यतः temporal safety (double free / use-after-free) पर ध्यान देता है, spatial bounds पर नहीं।
  • Ownership type system का हिस्सा है, attributes का नहीं, इसलिए owner वापस करने के लिए function return type को annotate करना पड़ता है; moves track किए जाते हैं, और moved-from owners वाले scopes को “destroy” करने के लिए मजबूर नहीं किया जाता।
  • सिस्टम non-pointer values (handles) को भी owners की तरह treat कर सकता है, जिससे custom allocators और handle-based designs संभव होते हैं।

Retrofit और composability

  • यह चिंता बहुत मजबूत है कि ownership APIs को “infect” करती है: एक बार कोई function owner return करे, तो callers और उनके callers को भी annotations अपनाने पड़ते हैं।
  • Cake के author इसे header में const जोड़ने जैसी स्थिति से मिलाते हैं: बदलाव व्यापक रूप से फैलते हैं, लेकिन समय के साथ स्थिर हो जाते हैं।
  • Checks by default disabled रहते हैं; ownership.h include करने और __OWNERSHIP_H__ define करने से वे चालू हो जाते हैं। Macros एक ही code को ऐसे compilers के साथ compile करने देते हैं जो ownership support नहीं करते।
  • कुछ patterns (जैसे, linked lists) साफ़-सुथरे तरीके से काम करते दिखाए गए हैं; Cake के अपने code की कुछ functions में checks बहुत awkward होने पर disabled हैं।

सुरक्षा गारंटी और सीमाएँ

  • वर्तमान ध्यान temporal safety पर है; out-of-bounds और general UB अभी संभाले नहीं जाते। Nullable references और lifetime-जैसी analyses की योजना है, लेकिन वे अधूरी हैं।
  • Static analysis को दुर्लभ रूप से चलने वाले paths के लिए मूल्यवान माना जाता है, जहाँ runtime tools कभी trigger नहीं हो सकते।
  • इस बात पर बहस है कि “optional” safety (per-file defines, checks को silence करने की क्षमता) क्या वाकई आकर्षक है, या लक्ष्य full memory safety होना चाहिए।

Rust, RAII, mempools, isoheaps से तुलना

  • Rust के ownership/borrow model से बार-बार तुलना की जाती है: moves और drops में समानताएँ हैं, लेकिन dynamic drop semantics और explicit lifetimes में अंतर है।
  • Cake, C++ RAII से अलग है: destruction unconditional नहीं है; flow analysis तय करती है कि destruction आवश्यक है या नहीं।
  • कुछ लोगों का तर्क है कि एक अच्छा mempool या isoheaps समान सुरक्षा दे सकते हैं; दूसरे जवाब देते हैं कि ये UB को व्यापक रूप से संबोधित नहीं करते, और static ownership checking के समकक्ष नहीं हैं।
  • “Half measures” जो फिर भी bugs की अनुमति देती हैं, और strict models जो architectural change को मजबूर करते हैं, इनके बीच तनाव है।

Tooling, integration, और ecosystem मुद्दे

  • Cake एक standalone C23 frontend है जो C99/C89 output कर सकता है, और compiler तथा static analyzer दोनों के रूप में उपयोग होता है।
  • Empty ownership macros का उपयोग करके यह GCC/Clang के साथ coexist कर सकता है; plugin-जैसी integration में रुचि है।
  • व्यावहारिक सफलता इस पर निर्भर करती है कि OpenSSL जैसी जटिल वास्तविक libraries को annotate किया जाए, जिसे भविष्य का काम माना गया है।