(पृष्ठभूमि: मुझे C और C ++ कंपाइलर को लागू करने का कुछ अनुभव है।)
C99 में चर-लंबाई सरणियाँ मूल रूप से एक गलत कदम था। वीएलए का समर्थन करने के लिए, C99 को सामान्य ज्ञान के लिए निम्नलिखित रियायतें देनी थीं:
sizeof x
अब हमेशा एक संकलन-समय स्थिर नहीं रहता है; संकलक को कभी-कभी sizeof
रन-टाइम पर एक- डेक्प्रेशन का मूल्यांकन करने के लिए कोड उत्पन्न करना चाहिए ।
द्वि-आयामी VLAs ( int A[x][y]
) की अनुमति देते हुए 2 डी VLAs पैरामीटर के रूप में कार्य करने वाले कार्यों की घोषणा के लिए एक नए सिंटैक्स की आवश्यकता है void foo(int n, int A[][*])
:।
C ++ दुनिया में कम महत्वपूर्ण है, लेकिन एम्बेडेड सिस्टम सिस्टम प्रोग्रामर के C लक्षित दर्शकों के लिए अत्यंत महत्वपूर्ण है, VLA घोषित करने का मतलब है कि आपके स्टैक का एक मनमाने ढंग से बड़ा हिस्सा काटना। यह एक गारंटीकृत स्टैक-ओवरफ्लो और क्रैश है। (जब भी आप घोषणा करते हैं int A[n]
, आप स्पष्ट रूप से दावा कर रहे हैं कि आपके पास 2 जीबी स्टैक है स्पेयर करने के लिए। आखिरकार, यदि आप जानते हैं कि " n
निश्चित रूप से यहां 1000 से कम है", तो आप बस घोषित करेंगे int A[1000]
। 32-बिट पूर्णांक के n
लिए प्रतिस्थापन 1000
एक प्रवेश है। आपको पता नहीं है कि आपके कार्यक्रम का व्यवहार क्या होना चाहिए। "
ठीक है, तो चलिए अब C ++ के बारे में बात करते हैं। C ++ में, हमारे पास "टाइप सिस्टम" और "वैल्यू सिस्टम" के बीच समान मजबूत अंतर है जो C89 करता है ... लेकिन हमने वास्तव में उन तरीकों पर भरोसा करना शुरू कर दिया है जो C ने नहीं किए हैं। उदाहरण के लिए:
template<typename T> struct S { ... };
int A[n];
S<decltype(A)> s; // equivalently, S<int[n]> s;
यदि n
एक संकलन-समय स्थिर नहीं था (यानी, यदि A
वैरिएबल संशोधित प्रकार के थे), तो पृथ्वी पर क्या प्रकार होगा S
? चाहेंगे S
के प्रकार भी केवल रनटाइम पर निर्धारित किया?
इस बारे में क्या:
template<typename T> bool myfunc(T& t1, T& t2) { ... };
int A1[n1], A2[n2];
myfunc(A1, A2);
संकलक को कुछ तात्कालिकता के लिए कोड उत्पन्न करना चाहिए myfunc
। उस कोड को कैसा दिखना चाहिए? यदि हम A1
संकलित समय के प्रकार को नहीं जानते हैं, तो हम वैधानिक रूप से उस कोड को कैसे उत्पन्न कर सकते हैं ?
इससे भी बदतर, क्या होगा अगर यह रनटाइम पर निकलता है n1 != n2
, ताकि !std::is_same<decltype(A1), decltype(A2)>()
? उस स्थिति में, कॉल को myfunc
संकलित नहीं किया जाना चाहिए , क्योंकि टेम्पलेट प्रकार की कटौती विफल होनी चाहिए! हम संभवतः उस व्यवहार को रनटाइम में कैसे अनुकरण कर सकते हैं?
मूल रूप से, C ++ अधिक -से- अधिक निर्णयों को संकलन-समय में धकेलने की दिशा में आगे बढ़ रहा है : टेम्प्लेट कोड पीढ़ी, constexpr
फ़ंक्शन मूल्यांकन, और इसी तरह। इस बीच, C99 पारंपरिक रूप से आगे बढ़ाने में व्यस्त था संकलन समय निर्णय (जैसे sizeof
) में क्रम । इसे ध्यान में रखते, यह वास्तव में भी भावना किसी भी प्रयास में खर्च करने पड़ता है की कोशिश कर रहा सी में C99 शैली Vlas एकीकृत करने के लिए ++?
के रूप में हर दूसरे उत्तर देने पहले ही बताया गया है, सी ++ ढेर-आवंटन तंत्र के बहुत सारे प्रदान करता है ( std::unique_ptr<int[]> A = new int[n];
या std::vector<int> A(n);
स्पष्ट लोगों जा रहा है) जब तुम सच में विचार व्यक्त करना चाहता "मैं पता नहीं कितनी RAM मैं आवश्यकता हो सकती है है।" और C ++ अपरिहार्य स्थिति से निपटने के लिए एक निफ्टी अपवाद-हैंडलिंग मॉडल प्रदान करता है कि आपके द्वारा आवश्यक RAM की मात्रा आपके पास RAM की मात्रा से अधिक है। लेकिन उम्मीद है कि यह उत्तर आपको एक अच्छा विचार देता है कि C99 शैली के वीएलएए सी + + के लिए एक अच्छा फिट क्यों नहीं थे - और वास्तव में सी 99 के लिए एक अच्छा फिट भी नहीं है। ;)
इस विषय पर अधिक जानकारी के लिए, N3810 "ऐरे एक्सटेंशन के लिए विकल्प" , ब्रेज़न स्ट्रॉस्ट्रुप का वीवीएएस पर अक्टूबर 2013 का पेपर देखें। बज़्ने की पीओवी खदान से बहुत अलग है; N3810 चीजों के लिए एक अच्छा C ++ ish सिंटैक्स खोजने पर अधिक ध्यान केंद्रित करता है, और C ++ में कच्चे सरणियों के उपयोग को हतोत्साहित करने पर, जबकि मैंने मेटाप्रोग्रामिंग और टाइपिस्ट के लिए निहितार्थ पर अधिक ध्यान केंद्रित किया है। मुझे नहीं पता कि क्या वह मेटाप्रोग्रामिंग / टाइपसिस्टम निहितार्थ को हल करता है, सॉल्व करता है, या केवल निर्बाध मानता है।
एक अच्छा ब्लॉग पोस्ट जो इन समान बिंदुओं में से कई को हिट करता है, "वैरिएबल यूज ऑफ वेरिएबल लेंथ एरेस " (क्रिस वेल्स, 2019-10-27)।