पॉइंटर्स कब और क्यों जोखिम भरे होने लगे?


18

ऐसा लगता है कि प्रोग्रामिंग लैंग्वेज में पॉइंटर्स के उपयोग के बारे में सोच में धीरे-धीरे बदलाव आया है, क्योंकि यह आम तौर पर स्वीकार किया जाता है कि पॉइंटर्स को जोखिम भरा माना जाता था (यदि एकमुश्त "बुराई" या इसी तरह के एग्रीगेंडेसेम नहीं)।

इस बदलाव के लिए ऐतिहासिक घटनाक्रम क्या थे? क्या विशिष्ट, सेमिनल इवेंट्स, रिसर्च या अन्य घटनाक्रम थे?

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

नोट: मैं पॉइंटर्स बनाम संदर्भों की वास्तविक खूबियों बनाम कुछ और के बारे में नहीं पूछ रहा हूं। मेरा ध्यान इस स्पष्ट बदलाव के लिए तर्क पर है।


1
यह लिबरल आर्ट्स शिक्षा की गिरावट के कारण था। लोग अब सभी सीपीयू में शामिल कंप्यूटिंग तकनीक में सबसे मौलिक विचारों में से एक, अप्रत्यक्ष संदर्भ को समझ नहीं सकते हैं।

10
संकेत दिए गए हैं जोखिम भरा। आपको क्यों लगता है कि सोच में बदलाव आया है? भाषा की विशेषताओं और हार्डवेयर में सुधार हुए हैं जो बिना पॉइंटर्स के सॉफ्टवेयर लिखने की अनुमति देते हैं, हालांकि कुछ प्रदर्शन जुर्माना के बिना नहीं।
मोनिका

4
@DaveInCaz जहां तक ​​मुझे पता है कि विशिष्ट विकास बिंदुओं का आविष्कार था।
मोनिका

5
@nocomprende: आपने अभी जो लिखा है वह तथ्य नहीं है और न ही सबूत, सिर्फ राय। 1970 में बहुत कम प्रोग्रामर थे, आपके पास कोई सबूत नहीं है कि जनसंख्या आज "अप्रत्यक्ष संदर्भ" में बेहतर या बदतर है।
whatsisname

3
पॉइंटर्स को हमेशा से ही जोखिम भरा माना जाता रहा है। यह उन्हें विधानसभा से उच्च स्तर की भाषाओं में स्थानांतरित करने के लिए बस एक समझौता था।
फ्रैंक हिलमैन

जवाबों:


21

औचित्य बिंदुओं के विकल्प का विकास था।

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

यह हमेशा "खतरनाक" था, लेकिन खतरा सापेक्ष है। जब आप 1000 लाइन का कार्यक्रम बना रहे हों, या जब आपके पास आईबीएम-ग्रेड सॉफ्टवेयर गुणवत्ता प्रक्रियाएं हों, तो इस खतरे को आसानी से दूर किया जा सकता है। हालांकि, उस तरह से सभी सॉफ्टवेयर विकसित नहीं किए जा रहे थे। जैसे, सरल संरचनाओं की इच्छा सामने आई।

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

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

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

ब्याज की भी कार्यात्मक भाषाएं होंगी, जिनकी ऐसी कोई अवधारणा नहीं है, लेकिन यह बहुत अलग चर्चा है।


3
मुझे यकीन नहीं है कि यह कहना सही है कि जावा में कोई संकेत नहीं है। मैं इस बारे में लंबी बहस में नहीं पड़ना चाहता कि क्या है और एक पॉइंटर नहीं है लेकिन जेएलएस का कहना है कि "एक संदर्भ का मूल्य एक पॉइंटर है"। अनुमति देने वाले पॉइंटर्स की कोई सीधी पहुंच या संशोधन नहीं है। यह सिर्फ सुरक्षा के लिए नहीं है, लोगों को किसी भी क्षण किसी वस्तु पर नज़र रखने के व्यवसाय से बाहर रखना जीसी के लिए मददगार है।
जिमीजम्स

6
@JimmyJames सच। इस उत्तर के प्रयोजनों के लिए, पॉइंटर और न-पॉइंटर के बीच की विभाजन रेखा यह थी कि क्या यह पॉइंटर अंकगणितीय कार्यों का समर्थन करता था, जो आमतौर पर संदर्भों द्वारा समर्थित नहीं होते हैं।
कॉर्ट अमोन -

8
@JimmyJames मैं कॉर्ट के दावे के साथ कहता हूं कि एक पॉइंटर कुछ ऐसा है जिस पर आप अंकगणितीय ऑपरेशन कर सकते हैं, जबकि एक संदर्भ नहीं है। जावा जैसी भाषाओं में संदर्भ को लागू करने वाला वास्तविक तंत्र एक कार्यान्वयन विवरण है।
रॉबर्ट हार्वे

3
सामान्य तौर पर, सी और सी ++ ने स्वेच्छा से इस खतरनाक क्लब में सदस्यता को "अपरिभाषित व्यवहार" के कई विनिर्देशन में अनुमति देकर स्वीकार कर लिया था।
rwong

2
वैसे, वहाँ रहे हैं सीपीयू, जो संकेत दिए गए और संख्या के बीच अंतर। उदाहरण के लिए आईबीएम एएस / 400 में मूल 48-बिट सीआईएससी सीपीयू है। और वास्तव में, वहाँ एक अमूर्त परत ओएस, जिसका अर्थ है कि न केवल सीपीयू संख्या और संकेत के बीच भेद और संकेत पर अंकगणित न करे करता नीचे है, लेकिन ओएस खुद भी संकेत दिए गए के बारे में पता नहीं है सब पर और न भाषाओं करना । दिलचस्प है, यह मूल AS / 400 को एक प्रणाली बनाता है, जहां C में उच्च-स्तरीय स्क्रिप्टिंग भाषा से कोड को फिर से लिखना इसे परिमाण धीमे के आदेश बनाता है ।
जोर्ग डब्ल्यू मित्तग

10

जटिल कार्यक्रमों (जैसे पुनरावर्ती या चर-आकार डेटा संरचनाओं) के लिए किसी प्रकार का अप्रत्यक्ष उपयोग आवश्यक है। हालाँकि, संकेत के माध्यम से इस अप्रत्यक्ष को लागू करना आवश्यक नहीं है।

अधिकांश उच्च स्तरीय प्रोग्रामिंग भाषाएं (अर्थात असेंबली नहीं) काफी मेमोरी-सेफ हैं और अप्रतिबंधित पॉइंटर एक्सेस को अस्वीकार करती हैं। C परिवार यहाँ एक विषम है।

C, B से बाहर निकलता है जो कच्ची सभा के ऊपर एक बहुत पतली अमूर्तता थी। बी का एक ही प्रकार था: शब्द। इस शब्द का उपयोग पूर्णांक या सूचक के रूप में किया जा सकता है। जब पूरी मेमोरी को एकल सन्निहित सरणी के रूप में देखा जाता है, तो वे दो समतुल्य होती हैं। सी ने इसे अधिक लचीला दृष्टिकोण रखा और स्वाभाविक रूप से असुरक्षित सूचक अंकगणित का समर्थन करना जारी रखा। सी के पूरे प्रकार की प्रणाली एक बाद की बात है। मेमोरी एक्सेस का यह लचीलापन C को उसके प्राथमिक उद्देश्य के लिए बहुत उपयुक्त बनाता है: यूनिक्स ऑपरेटिंग सिस्टम को प्रोटोटाइप करना। बेशक यूनिक्स और सी काफी लोकप्रिय रहे, इसलिए कि सी का उपयोग उन अनुप्रयोगों में भी किया जाता है जहां स्मृति के लिए इस निम्न-स्तरीय दृष्टिकोण की वास्तव में आवश्यकता नहीं है।

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

गार्बेज कलेक्शन 50 के दशक के उत्तरार्ध से, यानी सी (70 के दशक से पहले) तक मौजूद था। जीसी को ठीक से काम करने के लिए मेमोरी सुरक्षा की आवश्यकता होती है। C से पहले और बाद की भाषाओं ने GC को एक सामान्य सुविधा के रूप में इस्तेमाल किया। बेशक जो भाषा को बहुत अधिक जटिल और संभवतः धीमा बना देता है, जो मुख्य रूप से मेनफ्रेम के समय में ध्यान देने योग्य था। जीसी भाषाओं को अनुसंधान-उन्मुख (जैसे लिस्प, सिमुला, एमएल) और / या शक्तिशाली वर्कस्टेशन (जैसे स्मॉलकॉल) की आवश्यकता होती है।

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

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

इसलिए जावा, रूबी और सी # जैसी "आधुनिक" भाषाओं की व्याख्या सी की तरह कच्चे पॉइंटर्स की समस्याओं पर काबू पाने के रूप में नहीं की जानी चाहिए, बल्कि कई परंपराओं से ड्राइंग के रूप में देखी जानी चाहिए - सी सहित, लेकिन स्मालटाक, सिमुला जैसी सुरक्षित भाषाओं से भी, या लिस्प।


4

मेरे अनुभव में, संकेत कई लोगों के लिए एक चुनौतीपूर्ण अवधारणा रहे हैं। 1970 में, मैं जिस विश्वविद्यालय में जा रहा था, वहां एक बरोज़ B5500 था, और हमने अपनी प्रोग्रामिंग परियोजनाओं के लिए विस्तारित अल्गोल का उपयोग किया। हार्डवेयर आर्किटेक्चर डेटा वर्ड के ऊपरी हिस्से में डिस्क्रिप्टर और कुछ कोड पर आधारित था। इन्हें स्पष्ट रूप से अंत में चलने की अनुमति दिए बिना सरणियों का उपयोग करने देने के लिए डिज़ाइन किया गया था।

नाम बनाम मूल्य संदर्भ और B5500 सरणियों ने कैसे काम किया, इस बारे में हमने कक्षा में चर्चा की थी। हममें से कुछ को तुरंत स्पष्टीकरण मिल गया। दूसरों ने नहीं किया।

बाद में, यह कुछ हद तक एक झटका था कि हार्डवेयर मुझे भगोड़ा बिंदुओं से नहीं बचाता था - विशेष रूप से विधानसभा भाषा में। स्नातक होने के बाद अपनी पहली नौकरी पर, मैंने एक ऑपरेटिंग सिस्टम में समस्याओं को ठीक करने में मदद की। अक्सर हमारे पास एकमात्र दस्तावेज था जो मुद्रित दुर्घटना डंप था। मैंने मेमोरी डंप में रनवे पॉइंटर्स का स्रोत खोजने के लिए एक नॉक विकसित किया, इसलिए सभी ने मुझे पता लगाने के लिए "असंभव" डंप दिया। किसी भी अन्य प्रकार की त्रुटि की तुलना में हमें सूचक त्रुटियों के कारण अधिक समस्याएं थीं।

मैंने जिन लोगों के साथ काम किया है उनमें से कई ने फोरट्रान लिखना शुरू कर दिया है, फिर सी में चले गए, सी लिखा कि फोरट्रान की तरह बहुत कुछ था, और पॉइंटर्स से बचा गया। क्योंकि उन्होंने कभी संकेत और संदर्भों को आंतरिक नहीं किया, जावा ने समस्याएं खड़ी कीं। अक्सर, यह FORTRAN प्रोग्रामर के लिए यह समझने के लिए चुनौतीपूर्ण है कि ऑब्जेक्ट असाइनमेंट वास्तव में कैसे काम करता है।

आधुनिक भाषाओं ने टाइपो और अन्य त्रुटियों से हमें सुरक्षित रखते हुए "हुड के नीचे" की आवश्यकता वाले चीजों को करना आसान बना दिया है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.