C23: C का थोड़ा बेहतर रूप
C23, C भाषा मानक का नवीनतम संस्करण, `auto` type deduction, `typeof`, `static_assert` के keyword रूप, साफ़ initialization syntax, और trigraphs तथा K&R-शैली function definitions जैसे विरासत constructs को हटाने जैसी क्रमिक सुविधाएँ पेश करता है। टिप्पणीकार इस बात पर बँटे हुए हैं कि क्या ये बदलाव C को वास्तव में बेहतर बनाते हैं: कुछ लोग बेहतर generic macros, checked arithmetic, और मौजूदा compiler extensions तथा C++ के साथ अधिक तालमेल का स्वागत करते हैं, जबकि दूसरे इन्हें सतही बदलाव मानते हैं जो strings, modules, और सुरक्षित resource management जैसी दीर्घकालिक समस्याओं को नहीं छूते। चर्चा C23 को एक व्यापक परिदृश्य में भी रखती है जहाँ कई नए systems projects C++ या Rust को चुनते हैं, और जहाँ वैकल्पिक भाषाएँ (Zig, D, Nim, Ada, आदि) अधिक सुरक्षित या अधिक ergonomic C interop देने की प्रतिस्पर्धा करती हैं।
C23 में Auto, typeof, और “generics”
autoका फिर से उपयोग कुछ लोगों को अजीब विकल्प लगता है; कई लोगों को लगता है कि गंभीर C कोड में यह एक स्टाइल “no-no” माना जाएगा, C++ के विपरीत।- दूसरे लोग तर्क देते हैं कि C में यह सचमुच उपयोगी है:
- लंबे type नामों और
struct/enumprefixes से बचाता है। - generic macros के साथ मदद करता है (जैसे
SWAP(a,b)मेंauto tmp = a;) और fixed-width integer types के साथ भी। - मौजूदा
__auto_typeextensions को standard बनाता है।
- लंबे type नामों और
typeofभी जोड़ा गया है; कुछ लोग नोट करते हैं कि अब आपconst typeof(var1) tmp = var1;लिख सकते हैं।- इस पर बहस है कि
_Genericसच में “generics” कहलाता है या नहीं: कुछ इसे overloading/type-based switch मानते हैं, parametric data structures नहीं; दूसरे कहते हैं कि यह फिर भी “generic” की कसौटी पर खरा उतरता है।
C23 के अन्य भाषा-सम्बंधी बदलाव
static_assertअब एक keyword बन जाता है; C11 में पहले से_Static_assertऔर एक macro था, लेकिन अब यह<assert.h>के बिना भी उपयोग किया जा सकता है।func()अब स्पष्ट रूप सेfunc(void)के बराबर है, और unnamed parameters की अनुमति है।{}के साथ struct initialization (zero-init) अब वैध है (struct foo x = {};), जिससे C++ के साथ तालमेल बनता है।- trigraphs और पुराने K&R-शैली function declarations को हटाने का स्वागत किया गया है, क्योंकि ये ऐतिहासिक विचित्रताओं को साफ करते हैं।
- कुछ लोग चाहते हैं कि C23 में built-in
defer/RAII फीचर होता; ऐसा एक proposal मौजूद है, लेकिन अभी भी “exploratory” है।
Toolchain और compiler support
- cppreference के संदर्भ से कहा गया कि GCC 13 में C23 support अपेक्षाकृत व्यापक है; Clang कई features में पीछे है।
- इसके कारणों में LLVM का modular design और corporate forks का front-end evolution को धीमा करना बताया गया; बड़े contributors का ध्यान backends या अन्य भाषाओं पर रहता है।
- Pelles C के बारे में कहा गया कि यह लगभग सभी C23 features, including
#embed, support करता है। - MSVC ने ऐतिहासिक रूप से C को कम महत्व दिया, लेकिन हाल में C17 support करता है (कुछ optional C99 features को छोड़कर); भविष्य में C23 support कब होगा, यह स्पष्ट नहीं है।
C बनाम C++ और language philosophy
- कुछ लोग तर्क देते हैं कि C++ पहले से ही “a better C” है और C23 मुख्यतः C++ features को backport कर रहा है।
- दूसरे जवाब देते हैं कि C और C++ अब अलग-अलग domains की सेवा करते हैं; C++ की complexity, meta-programming, और hidden code generation को कुछ embedded/low-level use cases के लिए अनुपयुक्त माना जाता है।
- Analogies अलग-अलग हैं: “C++ is a cybertruck to C’s bicycle” (जिसे inaccurate कहा गया) से लेकर “C is hand tools, C++ adds power tools” तक।
- embedded में exceptions और RAII पर बहस: कुछ कहते हैं कि RAII सीधा और उपयोगी है; दूसरे object lifetimes के कम explicit होने को लेकर चिंतित हैं।
Headers, modules, और API surface
- कुछ लोग चाहते हैं कि C में headers के बजाय true modules/imports हों, ताकि duplication से बचा जा सके और builds तेज हों, संभवतः legacy
#includeके साथimportभी हो। - दूसरे लोग C के separate header/implementation split को पसंद करते हैं, क्योंकि इससे public API स्पष्ट रूप से expose होती है; और यह इस बात से अलग है कि भाषा में module system है या नहीं।
- चर्चा यह भी कहती है कि stronger modules कुछ C/C++ interoperability को तोड़ सकते हैं, जो राजनीतिक रूप से संवेदनशील है।
Memory-safe alternatives और C FFI
- एक लंबा subthread “small, stable, memory-safe languages with excellent C FFI and no big performance loss” पर चर्चा करता है।
- जिन candidates का उल्लेख हुआ उनमें Zig, D, Rust, Nim, V, Vala, LuaJIT, Ada, विभिन्न Schemes और Lisps, Swift, Julia, और Go शामिल हैं।
- Tradeoffs पर जोर दिया गया:
- सच्ची memory safety अक्सर GC या Rust-शैली borrowing मांगती है; दोनों FFI और/या simplicity को जटिल बनाते हैं।
- आसान, zero-overhead C FFI strong safety guarantees को कमजोर कर सकता है (bugs C से भीतर आ सकते हैं)।
- कई टिप्पणीकारों का कहना है कि मांगी गई पूरी wishlist को पूरी तरह संतुष्ट करना असंभव हो सकता है; अलग-अलग compromises के साथ केवल approximation ही संभव है।