कॉन्स्ट (कंप्यूटर प्रोग्रामिंग)

कुछ प्रोग्रामिंग लैंग्वेजेज में, कॉन्स्ट (const) एक प्रकार क्वालीफायर टाइप करें (डेटा प्रकार पर लागू एक कीवर्ड (कंप्यूटर प्रोग्रामिंग)) है जो इंगित करता है कि डेटा केवल पढ़ने के लिए है। जबकि इसका उपयोग कॉन्स्टेंट (कंप्यूटर प्रोग्रामिंग) घोषित करने के लिए किया जा सकता है, const सी-परिवार की सूची में लैंग्वेजेज की प्रोग्रामिंग लैंग्वेजएं प्रकार का हिस्सा होने के कारण अन्य लैंग्वेजेज में समान निर्माणों से भिन्न होती हैं, और इस प्रकार पॉइंटर (कंप्यूटर प्रोग्रामिंग), संदर्भ, समग्र डेटा प्रकार और प्रकार-चेकिंग  के साथ संयुक्त होने पर जटिल व्यवहार होता है। अन्य लैंग्वेजेज में, डेटा एक मेमोरी स्थान पर नहीं होता है, बल्कि प्रत्येक उपयोग पर संकलन समय पर कॉपी किया जाता है। जो लैंग्वेजएँ इसका उपयोग करती हैं उनमें C (प्रोग्रामिंग लैंग्वेज), C++, D (प्रोग्रामिंग लैंग्वेज), जावास्क्रिप्ट, जूलिया (प्रोग्रामिंग लैंग्वेज), और रस्ट (प्रोग्रामिंग लैंग्वेज) शामिल हैं।

परिचय
जब किसी वस्तु (कंप्यूटर विज्ञान) घोषणा (कंप्यूटर प्रोग्रामिंग) में लागू किया जाता है, यह इंगित करता है कि वस्तु एक स्थिरांक (कंप्यूटर प्रोग्रामिंग) है: इसका मान (कंप्यूटर विज्ञान) एक चर (कंप्यूटर विज्ञान) के विपरीत, बदला नहीं जा सकता है। यह मूल उपयोग - स्थिरांक घोषित करने के लिए - कई अन्य लैंग्वेजेज में समानताएं हैं।

हालाँकि, अन्य लैंग्वेजेज के विपरीत, लैंग्वेजेज के C परिवार में  प्रकार का भाग है, वस्तु का भाग नहीं। उदाहरण के लिए, सी में, int const x = 1; एक वस्तु घोषित करता है   का   लिखें   प्रकार का हिस्सा है, जैसे कि इसे पार्स किया गया हो (int const) x - जबकि Ada (प्रोग्रामिंग लैंग्वेज) में, X : constant INTEGER := 1_ एक स्थिरांक (एक प्रकार की वस्तु) घोषित करता है   का   लिखें   वस्तु का हिस्सा है, लेकिन प्रकार का हिस्सा नहीं है

इसके दो सूक्ष्म परिणाम हैं. पहले तो,  अधिक जटिल प्रकार के भागों पर लागू किया जा सकता है - उदाहरण के लिए,   एक स्थिर पूर्णांक के लिए एक स्थिर सूचक घोषित करता है, जबकि   एक स्थिर पूर्णांक के लिए एक चर सूचक घोषित करता है, और   एक चर पूर्णांक के लिए एक स्थिर सूचक घोषित करता है। दूसरे, क्योंकि   प्रकार का भाग है, इसे प्रकार-जाँच के भाग के रूप में मेल खाना चाहिए। उदाहरण के लिए, निम्नलिखित कोड अमान्य है: क्योंकि तर्क  एक परिवर्तनीय पूर्णांक होना चाहिए, लेकिन   एक अचर पूर्णांक है. यह मिलान प्रोग्राम शुद्धता का एक रूप है, और इसे 'कॉन्स्ट-शुद्धता' के रूप में जाना जाता है। यह अनुबंध द्वारा प्रोग्रामिंग के एक रूप की अनुमति देता है, जहां फ़ंक्शन अपने प्रकार के हस्ताक्षर के हिस्से के रूप में निर्दिष्ट करते हैं कि क्या वे अपने तर्कों को संशोधित करते हैं या नहीं, और क्या उनका रिटर्न मान परिवर्तनीय है या नहीं। यह प्रकार-जांच मुख्य रूप से संकेतकों और संदर्भों में रुचि रखती है - पूर्णांक जैसे बुनियादी मूल्य प्रकार नहीं - बल्कि समग्र डेटा प्रकार या कंटेनर (सार डेटा प्रकार) जैसे टेम्पलेट प्रकारों के लिए भी। यह इस तथ्य से छिपा है कि  टाइप ज़बरदस्ती (अंतर्निहित प्रकार रूपांतरण) और सी के कॉल-टू-मूल्य से होने के कारण प्रायः छोड़ा जा सकता है (C++ और डी या तो कॉल-बाय-वैल्यू या कॉल-बाय-रेफरेंस हैं)।

परिणाम
कॉन्स्ट-नेस के विचार का अर्थ यह नहीं है कि स्मृति  में संग्रहीत चर अलेखनीय है। की अपेक्षा,  -नेस एक संकलन-समय निर्माण है जो इंगित करता है कि एक प्रोग्रामर को क्या करना चाहिए, जरूरी नहीं कि वे क्या कर सकते हैं। हालाँकि, ध्यान दें कि पूर्वनिर्धारित डेटा के मामले में (जैसे   स्ट्रिंग शाब्दिक), सी   प्रायः अलेखनीय होता है।

अचर से भेद
जबकि प्रोग्राम चलने के दौरान एक स्थिरांक अपना मान नहीं बदलता है, एक ऑब्जेक्ट घोषित किया जाता है  प्रोग्राम चलने के दौरान वास्तव में इसका मान बदल सकता है। एक सामान्य उदाहरण डिजिटल इनपुट की वर्तमान स्थिति जैसे एम्बेडेड सिस्टम के भीतर केवल पढ़ने योग्य रजिस्टर हैं। डिजिटल इनपुट के लिए डेटा रजिस्टर को प्रायः घोषित किया जाता है   और. इन रजिस्टरों की सामग्री प्रोग्राम के बिना कुछ भी किए बदल सकती है लेकिन आप उन्हें भी नहीं लिखेंगे.

अन्य उपयोग
इसके अतिरिक्त, एक (गैर स्थैतिक) सदस्य-फ़ंक्शन के रूप में घोषित किया जा सकता है. इस मामले में, यह (कंप्यूटर प्रोग्रामिंग)| ऐसे फ़ंक्शन के अंदर पॉइंटर प्रकार का होता है   केवल प्रकार के बजाय. इसका मतलब यह है कि इस ऑब्जेक्ट के लिए गैर-कॉन्स्ट फ़ंक्शंस को ऐसे फ़ंक्शन के अंदर से नहीं बुलाया जा सकता है, न ही फ़ील्ड (कंप्यूटर विज्ञान) को संशोधित किया जा सकता है। C++ में, एक सदस्य चर को इस प्रकार घोषित किया जा सकता है, यह दर्शाता है कि यह प्रतिबंध उस पर लागू नहीं होता है। कुछ मामलों में, यह उपयोगी हो सकता है, उदाहरण के लिए कैश (कंप्यूटिंग), संदर्भ गणना और डेटा सिंक्रनाइज़ेशन के साथ। इन मामलों में, वस्तु का तार्किक अर्थ (स्थिति) अपरिवर्तित है, लेकिन वस्तु भौतिक रूप से स्थिर नहीं है क्योंकि इसका बिटवाइज़ प्रतिनिधित्व बदल सकता है।

सिंटेक्स
C, C++ और D में, उपयोगकर्ता द्वारा परिभाषित डेटा सहित सभी डेटा प्रकार घोषित किए जा सकते हैं, और स्थिरांक-शुद्धता निर्देश देती है कि सभी चर या वस्तुओं को तब तक घोषित किया जाना चाहिए जब तक कि उन्हें संशोधित करने की आवश्यकता न हो। का ऐसा सक्रिय उपयोग   मूल्यों को समझना, ट्रैक करना और उनके बारे में तर्क करना आसान बनाता है, और इस प्रकार यह कोड की पठनीयता और बोधगम्यता को बढ़ाता है और टीमों में काम करना और कोड को बनाए रखना आसान बनाता है क्योंकि यह किसी मूल्य के इच्छित उपयोग के बारे में जानकारी संचारित करता है। यह कोड के बारे में तर्क करते समय  संकलक  के साथ-साथ डेवलपर को भी मदद कर सकता है। यह अधिक कुशल कोड उत्पन्न करने के लिए एक अनुकूलन कंपाइलर को भी सक्षम कर सकता है।

सरल डेटा प्रकार
सरल गैर-सूचक डेटा प्रकारों के लिए, इसे लागू करना  क्वालीफायर सीधा है. यह ऐतिहासिक कारणों से कुछ प्रकारों के दोनों ओर जा सकता है (उदाहरण के लिए,  के बराबर है  ). कुछ कार्यान्वयन पर, का उपयोग कर रहे हैं  दो बार (उदाहरण के लिए,   या  ) एक चेतावनी उत्पन्न करता है लेकिन कोई त्रुटि नहीं।

संकेत और संदर्भ
सूचक और संदर्भ प्रकार के लिए, का अर्थ  अधिक जटिल है - या तो सूचक स्वयं, या इंगित किया जा रहा मान, या दोनों, हो सकते हैं. इसके अलावा, वाक्यविन्यास भ्रमित करने वाला हो सकता है। एक सूचक को एक के रूप में घोषित किया जा सकता है  लिखने योग्य मान के लिए सूचक, या a के लिए लिखने योग्य सूचक   मूल्य, या   की ओर सूचक   कीमत। ए   पॉइंटर को प्रारंभ में असाइन किए गए ऑब्जेक्ट से भिन्न ऑब्जेक्ट को इंगित करने के लिए पुन: असाइन नहीं किया जा सकता है, लेकिन इसका उपयोग उस मान को संशोधित करने के लिए किया जा सकता है जिसे यह पॉइंटी कहा जाता है).     C++ में संदर्भ चर एक वैकल्पिक वाक्यविन्यास है   सूचक. ए के लिए एक सूचक   दूसरी ओर, ऑब्जेक्ट को किसी अन्य मेमोरी स्थान पर इंगित करने के लिए पुन: असाइन किया जा सकता है (जो एक ही प्रकार का या परिवर्तनीय प्रकार का ऑब्जेक्ट होना चाहिए), लेकिन इसका उपयोग उस मेमोरी को संशोधित करने के लिए नहीं किया जा सकता है जिसे वह इंगित कर रहा है। ए   ए की ओर सूचक   ऑब्जेक्ट को घोषित भी किया जा सकता है और इसका उपयोग न तो नियुक्त व्यक्ति को संशोधित करने के लिए किया जा सकता है और न ही किसी अन्य ऑब्जेक्ट को इंगित करने के लिए पुन: असाइन किया जा सकता है। निम्नलिखित कोड इन सूक्ष्मताओं को दर्शाता है:

सी कन्वेंशन
घोषणाओं के लिए सामान्य सी परंपरा का पालन करते हुए, घोषणा का उपयोग किया जाता है, और  एक पॉइंटर में पॉइंटर पर लिखा होता है, जो डीरेफ़रेंसिंग को दर्शाता है। उदाहरण के लिए, घोषणा में , असंदर्भित रूप   एक  , जबकि संदर्भ प्रपत्र   एक का सूचक है. इस प्रकार  नाम को इसके दाईं ओर संशोधित करता है। इसके बजाय C++ कन्वेंशन संबद्ध करने के लिए है   प्रकार के साथ, जैसे कि   और पढ़ें   बाईं ओर प्रकार को संशोधित करने के रूप में।   इस प्रकार पढ़ा जा सकता है  एक है  (मान स्थिर है), या  एक है  (सूचक एक स्थिर पूर्णांक का सूचक है)। इस प्रकार:

C++ सम्मेलन
मूल्य के बजाय प्रकार का विश्लेषण करने के C++ सम्मेलन के बाद, अंगूठे का एक नियम यह है कि घोषणा को दाएं से बाएं ओर पढ़ा जाए। इस प्रकार, तारे के बाईं ओर की हर चीज़ को नुकीले प्रकार के रूप में पहचाना जा सकता है और तारे के दाईं ओर की हर चीज़ को सूचक गुण के रूप में पहचाना जा सकता है। उदाहरण के लिए, उपरोक्त हमारे उदाहरण में,  एक लिखने योग्य सूचक के रूप में पढ़ा जा सकता है जो एक गैर-लिखने योग्य पूर्णांक को संदर्भित करता है, और   एक गैर-लिखने योग्य सूचक के रूप में पढ़ा जा सकता है जो एक लिखने योग्य पूर्णांक को संदर्भित करता है।

एक अधिक सामान्य नियम जो आपको जटिल घोषणाओं और परिलैंग्वेजेज को समझने में मदद करता है, इस तरह काम करता है:
 * 1) वह पहचानकर्ता ढूंढें जिसकी घोषणा आप समझना चाहते हैं
 * 2) जहां तक ​​संभव हो दाईं ओर पढ़ें (यानी, घोषणा के अंत तक या अगले समापन कोष्ठक तक, जो भी पहले आए)
 * 3) जहां से आपने शुरू किया था वहां वापस जाएं, और बाईं ओर पीछे की ओर पढ़ें (यानी, घोषणा की शुरुआत तक या पिछले चरण में पाए गए समापन कोष्ठक से मेल खाने वाले खुले-कोष्ठक तक)
 * 4) जब आप घोषणा की शुरुआत में पहुँच जाते हैं तो आपका काम पूरा हो जाता है। यदि नहीं, तो अंतिम मिलान किए गए समापन कोष्ठक से आगे, चरण 2 पर जारी रखें।

यहाँ एक उदाहरण है:

बाईं ओर पढ़ते समय, यह महत्वपूर्ण है कि आप तत्वों को दाईं से बाईं ओर पढ़ें। तो एक  यह एक const int के लिए एक सूचक बन जाता है, न कि एक int के लिए एक const सूचक।

कुछ मामलों में C/C++ इसकी अनुमति देता है  कीवर्ड को प्रकार के बाईं ओर रखा जाना चाहिए। यहां कुछ उदाहरण दिए गए हैं: हालाँकि C/C++ ऐसी परिलैंग्वेजेज की अनुमति देता है (जो परिलैंग्वेजेज को बाएं से दाएं पढ़ते समय अंग्रेजी लैंग्वेज से काफी मेल खाती हैं), कंपाइलर अभी भी उपरोक्त प्रक्रिया के अनुसार परिलैंग्वेजेज को पढ़ता है: दाएं से बाएं। लेकिन डाल रहा हूँ  इससे पहले कि क्या स्थिर होना चाहिए, आप जो लिखना चाहते हैं और कंपाइलर जो तय करता है कि आपने क्या लिखा है, के बीच बेमेल का परिचय देता है। पॉइंटर्स से पॉइंटर्स पर विचार करें:

सूचक परिलैंग्वेजेज के संबंध में अंतिम नोट के रूप में: सूचक प्रतीक (*) को सदैव यथासंभव दाईं ओर लिखें। सूचक प्रतीक को प्रकार से जोड़ना मुश्किल है, क्योंकि यह दृढ़ता से एक सूचक प्रकार का सुझाव देता है, जो कि मामला नहीं है। यहां कुछ उदाहरण दिए गए हैं: इस समस्या से बचने के लिए, Bjarne Stroustrup के FAQ में C++ कन्वेंशन का उपयोग करते समय प्रति पंक्ति केवल एक वेरिएबल घोषित करने की अनुशंसा की गई है। संदर्भों और प्रतिद्वंद्विता संदर्भों को परिभाषित करने पर भी यही विचार लागू होते हैं: पॉइंटर्स के लिए बहुआयामी सरणियों और संदर्भों (या पॉइंटर्स) का उपयोग करते समय अधिक जटिल घोषणाएँ सामने आती हैं। हालाँकि कभी-कभी इस पर बहस भी होती है कि ऐसी घोषणाएँ भ्रामक और त्रुटि-प्रवण हैं और इसलिए उन्हें टाला जाना चाहिए या उच्च-स्तरीय संरचनाओं द्वारा प्रतिस्थापित किया जाना चाहिए, इस खंड के शीर्ष पर वर्णित प्रक्रिया का उपयोग सदैव अस्पष्टता या भ्रम पैदा किए बिना किया जा सकता है।

पैरामीटर और चर
फ़ंक्शन पैरामीटर और वेरिएबल (वैश्विक या स्थानीय सहित स्थिर चर या स्वचालित) दोनों पर घोषित किया जा सकता है। उपयोग के बीच व्याख्या भिन्न-भिन्न होती है। ए  स्थिर चर (वैश्विक चर या स्थिर स्थानीय चर) एक स्थिरांक है, और इसका उपयोग गणितीय स्थिरांक जैसे डेटा के लिए किया जा सकता है, जैसे   - वास्तविक रूप से लंबा, या समग्र संकलन-समय पैरामीटर। a   स्वचालित चर (गैर स्थैतिक स्थानीय चर) का अर्थ है कि एकल असाइनमेंट हो रहा है, हालांकि हर बार एक अलग मान का उपयोग किया जा सकता है, जैसे कि. ए  पास-बाय-रेफरेंस में पैरामीटर का मतलब है कि संदर्भित मूल्य संशोधित नहीं है - यह अनुबंध द्वारा डिजाइन का हिस्सा है - जबकि ए   पास-बाय-वैल्यू में पैरामीटर (या पॉइंटर स्वयं, पास-बाय-रेफरेंस में) इंटरफ़ेस में कुछ भी नहीं जोड़ता है (जैसा कि मान कॉपी किया गया है), लेकिन इंगित करता है कि आंतरिक रूप से, फ़ंक्शन पैरामीटर की स्थानीय प्रतिलिपि को संशोधित नहीं करता है (यह एक एकल असाइनमेंट है)। इस कारण से, कुछ लोग इसका उपयोग करने के पक्ष में हैं   केवल पास-बाय-रेफरेंस के लिए पैरामीटर में, जहां यह अनुबंध बदलता है, लेकिन पास-बाय-वैल्यू के लिए नहीं, जहां यह कार्यान्वयन को उजागर करता है।

विधियाँ
उपयोगकर्ता-परिभाषित प्रकारों (संरचनाओं और वर्गों) के लिए डिज़ाइन-दर-अनुबंध दृष्टिकोण का लाभ उठाने के लिए, जिसमें विधियों के साथ-साथ सदस्य डेटा भी हो सकता है, प्रोग्रामर उदाहरण विधियों को  के रूप में टैग कर सकता है यदि वे ऑब्जेक्ट को संशोधित नहीं करते हैं डेटा सदस्य. इस प्रकार इंस्टेंस विधियों में  क्वालिफायर लागू करना कॉन्स्ट-शुद्धता के लिए एक आवश्यक सुविधा है और कई अन्य ऑब्जेक्ट-ओरिएंटेड भाषाओं जैसे जावा (प्रोग्रामिंग लैंग्वेज) और सी# या माइक्रोसॉफ्ट के C++/सीएलआई या C++ के लिए प्रबंधित एक्सटेंशन में उपलब्ध नहीं है।

जबकि  विधियों को कॉल किया जा सकता है   और गैर-  वस्तुएं समान, गैर-  विधियों को केवल गैर द्वारा ही लागू किया जा सकता है-  वस्तुएं. ई> इंस्टेंस विधि पर संशोधक द्वारा इंगित ऑब्जेक्ट पर लागू होता है सूचक, जो सभी उदाहरण विधियों को पारित एक अंतर्निहित तर्क है। इस प्रकार होना  पद्धतियाँ निहितार्थ पर स्थिरांक-शुद्धता लागू करने का एक तरीका है अन्य तर्कों की तरह ही सूचक तर्क।

यह उदाहरण दर्शाता है:

उपरोक्त कोड में, अन्तर्निहित की ओर सूचक  प्रकार है ; जहांकि की ओर सूचक   प्रकार है, यह दर्शाता है कि विधि इसके माध्यम से अपनी वस्तु को संशोधित नहीं कर सकती है सूचक.

प्रायः प्रोग्रामर दोनों की आपूर्ति करेगा  और एक गैर-  दोनों प्रकार के कॉलर्स को समायोजित करने के लिए एक कक्षा में एक ही नाम (लेकिन संभवतः काफी भिन्न उपयोग) वाली विधि है। विचार करना:

de>-कॉलिंग ऑब्जेक्ट की प्रकृति यह निर्धारित करती है कि कौन सा संस्करण है  लागू किया जाएगा और इस प्रकार कॉल करने वाले को एक संदर्भ दिया गया है या नहीं जिसके साथ वह हेरफेर कर सकता है या केवल ऑब्जेक्ट में निजी डेटा का निरीक्षण कर सकता है। दोनों विधियों में तकनीकी रूप से अलग-अलग हस्ताक्षर हैं क्योंकि उनका पॉइंटर्स के विभिन्न प्रकार होते हैं, जिससे कंपाइलर को सही पॉइंटर्स चुनने की अनुमति मिलती है। (लौटते हुए ए  एक का संदर्भ , केवल वापस करने के बजाय   मूल्य के अनुसार, दूसरी विधि में अधिकता हो सकती है, लेकिन उसी तकनीक का उपयोग मनमाने प्रकारों के लिए किया जा सकता है, जैसा कि मानक टेम्पलेट लाइब्रेरी में होता है।)

स्थिरांक-शुद्धता में खामियां
C और C++ में शुद्ध स्थिरांक-शुद्धता में कई खामियां हैं। वे मुख्य रूप से उपस्थिता कोड के साथ अनुकूलता के लिए उपस्थित हैं।

पहला, जो केवल C++ पर लागू होता है, का उपयोग है, जो प्रोग्रामर को स्ट्रिप करने की अनुमति देता है   क्वालीफायर, किसी भी वस्तु को परिवर्तनीय बनाना है।

उपस्थिता कोड और लाइब्रेरीज़ का उपयोग करते समय क्वालीफायर को अलग करने की आवश्यकता उत्पन्न होती है जिन्हें संशोधित नहीं किया जा सकता है लेकिन जो स्थिर-सही नहीं हैं। उदाहरण के लिए, इस कोड पर विचार करें:

हालाँकि, किसी ऑब्जेक्ट को संशोधित करने का कोई भी प्रयास जो स्वयं घोषित हो  आईएसओ C++ मानक के अनुसार कास्ट कास्ट के परिणामस्वरूप अपरिभाषित व्यवहार होता है।

उपरोक्त उदाहरण में, यदि  घोषित वैश्विक, स्थानीय या सदस्य चर का संदर्भ देता है , या ढेर पर आवंटित एक वस्तु  , कोड केवल तभी सही है यदि   वास्तव में द्वारा बताए गए मान को संशोधित नहीं करता है.

सी लैंग्वेज में एक खामी की आवश्यकता है क्योंकि एक निश्चित स्थिति उपस्थित है। स्थिर भंडारण अवधि वाले चर को प्रारंभिक मान के साथ परिभाषित करने की अनुमति है। हालाँकि, इनिशियलाइज़र केवल स्ट्रिंग स्थिरांक और अन्य शाब्दिक जैसे स्थिरांक का उपयोग कर सकता है, और चर नाम जैसे गैर-स्थिर तत्वों का उपयोग करने की अनुमति नहीं है, चाहे इनिशियलाइज़र तत्व घोषित किए गए हों  या नहीं, या स्थैतिक अवधि चर घोषित किया जा रहा है या नहीं   या नहीं। आरंभ करने का एक गैर-पोर्टेबल तरीका है   वैरिएबल जिसमें स्थिर भंडारण अवधि होती है। बाद के असाइनमेंट के बाईं ओर सावधानीपूर्वक टाइपकास्ट का निर्माण करके, a   वैरिएबल को प्रभावी ढंग से हटाकर लिखा जा सकता है   विशेषता और इसे अन्य की तरह गैर-स्थिर तत्वों के साथ 'प्रारंभ' करना   चर और ऐसे। ए में लिखना   परिवर्तनीय इस तरह से इरादा के अनुसार काम कर सकता है, लेकिन यह अपरिभाषित व्यवहार का कारण बनता है और गंभीरता से स्थिरांक-शुद्धता का खंडन करता है:

एक और खामी C और C++ दोनों पर लागू होता है। विशेष रूप से, लैंग्वेजएँ निर्देश देती हैं कि सदस्य सूचक और संदर्भ इसके संबंध में उथले हैं -उनके स्वामियों की प्रकृति - अर्थात, एक युक्त वस्तु है   सब कुछ है   सदस्य पॉइंटी (और रेफरी) को छोड़कर अन्य सदस्य अभी भी परिवर्तनशील हैं। स्पष्ट करने के लिए, इस C++ कोड पर विचार करें:

यद्यपि वस्तु  पास किया   स्थिर है, जो इसके सभी सदस्यों को स्थिर बनाता है, पॉइंटी तक पहुंच योग्य है   अभी भी परिवर्तनीय है, हालाँकि यह दृष्टिकोण से वांछनीय नहीं हो सकता है  -शुद्धता क्योंकि   केवल पॉइंटी का स्वामी हो सकता है। इस कारण से, मेयर्स का तर्क है कि सदस्य संकेतकों और संदर्भों के लिए डिफ़ॉल्ट गहरा होना चाहिए -नेस, जिसे a द्वारा ओवरराइड किया जा सकता है   क्वालीफायर जब पॉइंटी कंटेनर के स्वामित्व में नहीं होता है, लेकिन यह रणनीति उपस्थिता कोड के साथ संगतता समस्याएं पैदा करेगी। इस प्रकार, ऐतिहासिक कारणों से, यह खामी C और C++ में खुली रहती है।

बाद वाले लूपहोल को पॉइंटर को a के पीछे छिपाने के लिए क्लास का उपयोग करके बंद किया जा सकता है -सही इंटरफ़ेस, लेकिन ऐसी कक्षाएं या तो सामान्य प्रतिलिपि शब्दार्थ का समर्थन नहीं करती हैं   ऑब्जेक्ट (जिसका अर्थ है कि युक्त वर्ग को सामान्य शब्दार्थ द्वारा कॉपी नहीं किया जा सकता है) या स्ट्रिपिंग की अनुमति देकर अन्य खामियों की अनुमति दें  -असावधानीपूर्वक या जानबूझकर नकल के माध्यम से।

अंत में, C मानक लाइब्रेरी में कई फ़ंक्शन C23 (C मानक संशोधन) से पहले स्थिरांक-शुद्धता का उल्लंघन करते हैं, क्योंकि वे a स्वीकार करते हैं  एक वर्ण स्ट्रिंग पर सूचक और एक गैर लौटाएँ-  एक ही स्ट्रिंग के एक भाग के लिए सूचक. और  इन कार्यों में से हैं। C++ मानक लाइब्रेरी के कुछ कार्यान्वयन, जैसे कि Microsoft कुछ फ़ंक्शंस के दो फ़ंक्शन ओवरलोडिंग संस्करण प्रदान करके इस खामी को बंद करने का प्रयास करें: a संस्करण और एक गैर- संस्करण।

समस्याएँ
स्थिरता को व्यक्त करने के लिए टाइप सिस्टम का उपयोग विभिन्न जटिलताओं और समस्याओं को जन्म देता है, और तदनुसार इसकी आलोचना की गई है और सी, C++ और डी के संकीर्ण सी परिवार के बाहर इसे नहीं अपनाया गया है। जावा और C, जो सी और C++ से काफी प्रभावित हैं, दोनों को स्पष्ट रूप से खारिज कर दिया गया है। -स्टाइल प्रकार क्वालीफायर, इसके बजाय पहचानकर्ता पर लागू होने वाले कीवर्ड द्वारा स्थिरता व्यक्त करते हैं (  जावा में,   और   C# में)। यहां तक ​​कि C और C++ के भीतर भी, का उपयोग   काफी भिन्न होता है, कुछ परियोजनाएँ और संगठन इसका लगातार उपयोग करते हैं, और अन्य इससे बचते हैं।

समस्या
ई> प्रकार क्वालीफायर कठिनाइयों का कारण बनता है जब किसी फ़ंक्शन का तर्क इस बात से अज्ञेय होता है कि इसका इनपुट स्थिर है या नहीं, लेकिन एक मान लौटाता है जो इनपुट के समान योग्य प्रकार का होना चाहिए। दूसरे शब्दों में, इन कार्यों के लिए, यदि इनपुट स्थिर (स्थिरांक-योग्य) है, तो रिटर्न मान भी होना चाहिए, लेकिन यदि इनपुट परिवर्तनशील है (नहीं) -योग्य), वापसी मूल्य भी होना चाहिए। क्योंकि इन फ़ंक्शंस के प्रकार के हस्ताक्षर अलग-अलग होते हैं, इसके लिए समान तर्क के साथ दो फ़ंक्शंस (या संभावित रूप से एकाधिक इनपुट के मामले में अधिक) की आवश्यकता होती है - सामान्य प्रोग्रामिंग का एक रूप।

यह समस्या विशेष रूप से सी मानक लाइब्रेरी में सरल कार्यों के लिए भी उत्पन्न होती है ; इस अवलोकन का श्रेय 1980 के दशक के मध्य में रिची द्वारा टॉम प्लम को दिया गया है।    e> फ़ंक्शन स्ट्रिंग में एक वर्ण का पता लगाता है; औपचारिक रूप से, यह चरित्र की पहली घटना के लिए एक सूचक लौटाता है   स्ट्रिंग में , और क्लासिक सी (के एंड आर सी) में इसका प्रोटोटाइप है: e> फ़ंक्शन इनपुट स्ट्रिंग को संशोधित नहीं करता है, लेकिन रिटर्न वैल्यू का उपयोग प्रायः कॉलर द्वारा स्ट्रिंग को संशोधित करने के लिए किया जाता है, जैसे: इस प्रकार एक ओर इनपुट स्ट्रिंग हो सकती है  (चूंकि यह फ़ंक्शन द्वारा संशोधित नहीं है), और यदि इनपुट स्ट्रिंग है   रिटर्न वैल्यू भी उतनी ही होनी चाहिए - सबसे सरल इसलिए क्योंकि यह बिल्कुल इनपुट पॉइंटर लौटा सकता है, यदि पहला अक्षर मेल खाता है - लेकिन दूसरी ओर रिटर्न वैल्यू नहीं होनी चाहिए   यदि मूल स्ट्रिंग नहीं थी , क्योंकि कॉल करने वाला मूल स्ट्रिंग को संशोधित करने के लिए पॉइंटर का उपयोग करना चाह सकता है।

C++ में यह फ़ंक्शन ओवरलोडिंग के माध्यम से किया जाता है, साधारणतया एक टेम्पलेट (C++)C++) के माध्यम से कार्यान्वित किया जाता है, जिसके परिणामस्वरूप दो फ़ंक्शन होते हैं, ताकि रिटर्न मान समान हो -इनपुट के रूप में योग्य प्रकार: इन्हें बदले में एक टेम्पलेट द्वारा परिभाषित किया जा सकता है: डी में इसे इसके माध्यम से नियंत्रित किया जाता है   कीवर्ड, जो स्थिरांक, अपरिवर्तनीय, या अयोग्य (परिवर्तनीय) के लिए वाइल्डकार्ड के रूप में कार्य करता है, उपज: हालाँकि, C में इनमें से कुछ भी संभव नहीं है क्योंकि C में फ़ंक्शन ओवरलोडिंग नहीं है, और इसके बजाय, इसे एक एकल फ़ंक्शन द्वारा नियंत्रित किया जाता है जहां इनपुट स्थिर है लेकिन आउटपुट लिखने योग्य है: यह मुहावरेदार सी कोड की अनुमति देता है लेकिन यदि इनपुट वास्तव में कॉन्स्ट-योग्य था, तो प्रकार की सुरक्षा का उल्लंघन करते हुए कॉन्स्ट क्वालिफायर को हटा देता है। यह समाधान रिची द्वारा प्रस्तावित किया गया था और बाद में इसे अपनाया गया। यह अंतर C और C++ की अनुकूलता की विफलताओं में से एक है।

C23 (C मानक संशोधन) के बाद से, इस समस्या को सामान्य कार्यों के उपयोग से हल किया जाता है।  और समस्या से प्रभावित अन्य कार्य वापस आ जाएंगे   यदि कोई उन्हें पास कर दिया गया है तो सूचक और यदि कोई अयोग्य सूचक उन्हें पास कर दिया गया है तो एक अयोग्य सूचक।

डी
के संस्करण 2 में, const से संबंधित दो कीवर्ड उपस्थित हैं।   e> कीवर्ड उस डेटा को दर्शाता है जिसे किसी भी संदर्भ के माध्यम से संशोधित नहीं किया जा सकता है।   e> कीवर्ड परिवर्तनशील डेटा के गैर-परिवर्तनीय दृश्य को दर्शाता है। C++ के विपरीत, डी   और   गहरे हैं या, और किसी भी चीज़ तक पहुंच योग्य है   या   वस्तु है   या   क्रमश।

डी में स्थिरांक बनाम अपरिवर्तनीय का उदाहरण डी में सकर्मक या गहरे स्थिरांक का उदाहरण

इतिहास
1981 में Bjarne Stroustrup द्वारा C में क्लासेस, C++ के पूर्ववर्ती के साथ पेश किया गया था, और इसे मूल रूप से कहा जाता था. प्रेरणा के संबंध में स्ट्रॉस्ट्रुप लिखते हैं: : इसने दो कार्य किए: एक प्रतीकात्मक स्थिरांक को परिभाषित करने के एक तरीके के रूप में जो दायरे और प्रकार के नियमों का पालन करता है (अर्थात, मैक्रो का उपयोग किए बिना) और स्मृति में किसी वस्तु को अपरिवर्तनीय मानने के एक तरीके के रूप में। मैक्रोज़ के स्कोप्ड और टाइप किए गए विकल्प के रूप में पहला उपयोग, फ़ंक्शन-जैसे मैक्रोज़ के लिए समान रूप से पूरा किया गया था  कीवर्ड. लगातार संकेत, और  डेनिस रिची द्वारा संकेतन का सुझाव दिया गया था और इसलिए इसे अपनाया गया।

फिर मानकीकरण के हिस्से के रूप में सी में अपनाया गया, और अन्य प्रकार के क्वालीफायर के साथ एएनएसआई सी (और बाद के संस्करणों) में दिखाई देता है,. एक और क्वालिफायर,, X3J11 समिति की दिसंबर 1987 की बैठक में सुझाव दिया गया था, लेकिन इसे अस्वीकार कर दिया गया था; इसका लक्ष्य अंततः पूरा हुआ   C99 में कीवर्ड. रिची इन परिवर्धनों का बहुत अधिक समर्थन नहीं करते थे, उनका तर्क था कि वे अपना महत्व नहीं रखते हैं, लेकिन अंततः मानक से उन्हें हटाने के लिए तर्क नहीं दिया। डी बाद में विरासत में मिला  C++ से, जहां इसे टाइप कंस्ट्रक्टर (टाइप क्वालिफायर नहीं) के रूप में जाना जाता है और इसमें दो और टाइप कंस्ट्रक्टर जोड़े गए हैं,   और , संबंधित उपयोग के मामलों को संभालने के लिए।

अन्य लैंग्वेजएँ
अन्य लैंग्वेजएँ प्रकार के निरंतरता भाग में C/C++ का अनुसरण नहीं करती हैं, हालाँकि उनमें प्रायः सतही रूप से समान संरचनाएँ होती हैं और वे इसका उपयोग कर सकती हैं  कीवर्ड. साधारणतया इसका उपयोग केवल स्थिरांक (स्थिर वस्तुओं) के लिए किया जाता है।

C# में एक है  कीवर्ड, लेकिन मौलिक रूप से भिन्न और सरल शब्दार्थ के साथ: इसका मतलब एक संकलन-समय स्थिरांक है, और यह प्रकार का हिस्सा नहीं है।

निम (प्रोग्रामिंग लैंग्वेज) में एक है  C# के समान कीवर्ड: यह प्रकार का हिस्सा बनने के बजाय एक संकलन-समय स्थिरांक भी घोषित करता है। हालाँकि, निम में, किसी भी अभिव्यक्ति से एक स्थिरांक घोषित किया जा सकता है जिसका संकलन समय पर मूल्यांकन किया जा सकता है। C# में, केवल C# अंतर्निर्मित प्रकारों को ही घोषित किया जा सकता है  ; कक्षाओं, संरचनाओं और सरणियों सहित उपयोगकर्ता-परिभाषित प्रकार नहीं हो सकते.

जावा के पास नहीं है  - इसके बजाय यह है , जिसे स्थानीय चर घोषणाओं पर लागू किया जा सकता है और पहचानकर्ता पर लागू होता है, प्रकार पर नहीं। ऑब्जेक्ट सदस्यों के लिए इसका एक अलग ऑब्जेक्ट-ओरिएंटेड उपयोग है, जो नाम की उत्पत्ति है।

जावा लैंग्वेज विशिष्टता का संबंध है  एक आरक्षित कीवर्ड के रूप में - यानी, जिसे परिवर्तनीय पहचानकर्ता के रूप में उपयोग नहीं किया जा सकता है - लेकिन इसमें कोई शब्दार्थ नहीं दिया गया है: यह एक आरक्षित शब्द है (इसे पहचानकर्ताओं में उपयोग नहीं किया जा सकता है) लेकिन एक कीवर्ड नहीं है (इसका कोई विशेष अर्थ नहीं है)। ऐसा माना जाता है कि कीवर्ड का आरक्षण C++-शैली को शामिल करने के लिए जावा लैंग्वेज के विस्तार की अनुमति देने के लिए हुआ   तरीके और सूचक   प्रकार। कार्यान्वयन के लिए एक एन्हांसमेंट अनुरोध टिकट   जावा सामुदायिक प्रक्रिया में शुद्धता उपस्थित है, लेकिन 2005 में इसे इस आधार पर बंद कर दिया गया था कि इसे बैकवर्ड-संगत तरीके से लागू करना असंभव था। समकालीन एडा 83 में स्वतंत्र रूप से एक स्थिर वस्तु और एक की धारणा थी  कीवर्ड,  इनपुट पैरामीटर और लूप पैरामीटर पूरी तरह से स्थिर हैं। यहां ही   वस्तु का गुण है, प्रकार का नहीं।

जावास्क्रिप्ट में एक है  घोषणा जो एक ब्लॉक-स्कोप्ड वैरिएबल को परिभाषित करती है जिसे पुन: असाइन नहीं किया जा सकता है और न ही पुनः घोषित किया जा सकता है। यह एक वेरिएबल के लिए केवल पढ़ने योग्य संदर्भ को परिभाषित करता है जिसे दोबारा परिभाषित नहीं किया जा सकता है, लेकिन कुछ स्थितियों में वेरिएबल का मान संभावित रूप से बदल सकता है, जैसे कि यदि वेरिएबल किसी ऑब्जेक्ट को संदर्भित करता है और इसकी एक संपत्ति बदल जाती है।

यह भी देखें

 * एकल असाइनमेंट
 * प्रतिबंध लगाना
 * सूचक उपनाम

बाहरी संबंध

 * "Const-Correctness" by Herb Sutter
 * "Constant Optimization?" by Herb Sutter
 * The C++ FAQ Lite: Const correctness by Marshall Cline
 * Section "Value substitution" from the free electronic book Thinking in C++ by Bruce Eckel
 * "Here A Const, There A Const" by Walter Bright
 * "Const and Invariant" from D programming language specification, version 2 (experimental)