2010-04-08 12 views
30

मुझे कुछ साल पहले इस बारे में पढ़ने की याद आ रही है, लेकिन मुझे नेट पर कोई संदर्भ नहीं मिल रहा है।जब नल मैक्रो 0 नहीं था?

क्या आप मुझे ऐसा उदाहरण दे सकते हैं जहां नल मैक्रो 0 तक विस्तार नहीं हुआ?

स्पष्टता के लिए संपादित करें: आज यह ((void *)0), (0), या (0L) तक फैलता है। हालांकि, आर्किटेक्चर लंबे समय से भूल गए थे जहां यह सच नहीं था, और न्यूल एक अलग पते पर विस्तारित हुआ। कुछ

#ifdef UNIVAC 
    #define NULL (0xffff) 
#endif 

मैं ऐसी मशीन का उदाहरण ढूंढ रहा हूं।

अद्यतन मुद्दों का समाधान करने के लिए:

मैं मौजूदा मानकों के संदर्भ में इस सवाल का मतलब नहीं था, या मेरे गलत शब्दावली के साथ लोगों को परेशान करने के लिए। हालांकि, स्वीकृत उत्तर से मेरी धारणाओं की पुष्टि की गई:

बाद के मॉडल [blah] का उपयोग करते थे, जाहिर है कि सभी मौजूदा खराब लिखित सी कोड के लिए एक सोप के रूप में गलत धारणाएं थीं।

वर्तमान मानक में शून्य पॉइंटर्स के बारे में चर्चा के लिए, this question देखें।

+1

'NULL' किसी पते पर विस्तार नहीं करता है। क्या आप सचमुच पूछ रहे हैं कि 'नल' मैक्रो को किसी और चीज के लिए परिभाषित किया गया था, या क्या आप पूछना चाहते हैं कि शून्य सूचक के अंतर्निहित प्रतिनिधित्व कब-बिट-शून्य नहीं हैं? – jamesdlin

+0

आखिरी मैंने देखा, यह या तो ((शून्य *) (3 एल - 2 एल - 1 एल)), (((((0) * 0x55))), या ('\ 0') तक विस्तारित हो सकता है। (सी में है। इनमें से कुछ को सी ++ में अनुमति नहीं दी जाएगी।) –

+1

आपके द्वारा स्वीकार किए गए उत्तर से आपके प्रश्न का उत्तर नहीं दिया गया है। या तो प्रश्न को सही करें (यदि वह नहीं है जिसे आप पूछना चाहते हैं), या किसी अन्य उत्तर को फिर से स्वीकार करें। विवरण टिप्पणियों में हैं। – AnT

उत्तर

30

सी एफएक्यू में गैर-0 पूर्ण प्रतिनिधित्व वाले ऐतिहासिक मशीनों के कुछ उदाहरण हैं।

The C FAQ List से

, question 5.17:

प्रश्न: गंभीरता से, किसी भी वास्तविक मशीनों वास्तव में अलग प्रकार के संकेत दिए गए के लिए अशून्य अशक्त संकेत दिए गए हैं या फिर विभिन्न अभ्यावेदन का इस्तेमाल किया है?

ए: प्राइम 50 श्रृंखला ने खंड 07777 का उपयोग किया, कम से कम पीएल/आई के लिए शून्य पॉइंटर के लिए ऑफसेट 0। बाद के मॉडल ने सी के लिएके लिए ऑफसेट 0 का उपयोग किया, टीसीएनपी (टेस्ट सी नल पॉइंटर) जैसे नए निर्देशों की जरुरत है, स्पष्ट रूप से [फुटनोट] के लिए एक एसओपी के रूप में सभी मौजूदा खराब लिखित सी कोड जो गलत धारणाएं बनाते हैं । पुराना, शब्द-संबोधित प्राइम मशीन भी शब्द पॉइंटर्स (int *) से बड़े बाइट पॉइंटर्स (char *) की आवश्यकता के लिए कुख्यात थे। चार * और शून्य *, और शब्द के लिए बाइट संकेत:

डाटा जनरल से The Eclipse एमवी श्रृंखला तीन वास्तुकला समर्थित सूचक प्रारूपों (शब्द, बाइट, और बिट संकेत), जिनमें से दो सी compilers द्वारा उपयोग किया जाता है बाकी सब कुछ के लिए पॉइंटर्स। के दौरान ऐतिहासिक कारणों के लिए 16-बिट नोवा लाइन से 32-बिट एमवी लाइन के विकास के लिए, शब्द पॉइंटर्स और बाइट पॉइंटर्स के पास ऑफ़सेट, संकेत, और अंगूठी शब्द में विभिन्न स्थानों में सुरक्षा बिट्स था। किसी फ़ंक्शन में एक विसंगित सूचक प्रारूप को पास करने से सुरक्षा त्रुटियां हुईं। आखिरकार, एमवी सी कंपाइलर ने को पॉइंटर प्रकार की मिस्चैच त्रुटियों वाले कोड से निपटने के लिए कई संगतता विकल्प जोड़े।

कुछ हनीवेल-बुल मेनफ्रेम (आंतरिक) शून्य पॉइंटर्स के लिए बिट पैटर्न 06000 का उपयोग करते हैं।

सीडीसी साइबर 180 सीरीज़ में 48-बिट पॉइंटर्स हैं जिनमें एक अंगूठी, सेगमेंट और ऑफसेट शामिल है। अधिकांश उपयोगकर्ता (अंगूठी 11 में) 0xB00000000000 के शून्य पॉइंटर्स हैं। पुरानी सीडीसी-पूरक मशीनों पर यह पर आम था, अमान्य पते सहित सभी प्रकार के डेटा, के लिए एक विशेष ध्वज के रूप में एक-एक-बिट शब्द का उपयोग करें।

पुरानी एचपी 3000 श्रृंखला शब्द पते के मुकाबले बाइट पते के लिए एक अलग एड्रेसिंग योजना का उपयोग करती है; से ऊपर की कई मशीनों की तरह यह इसलिए अन्य पॉइंटर्स के मुकाबले char * और शून्य * पॉइंटर्स के लिए अलग-अलग प्रस्तुतियों का उपयोग करता है।

सिंबलिक्स लिस्प मशीन, एक टैग की गई वास्तुकला में, पारंपरिक संख्यात्मक पॉइंटर्स भी नहीं है; यह एक सी नल सूचक के रूप में जोड़ी (मूल रूप से nonexistent हैंडल) का उपयोग करता है।

`` स्मृति मॉडल 'के आधार पर' प्रयोग में, 8086-परिवारिक प्रोसेसर (पीसी compatibles) 16-बिट डेटा संकेत दिए गए और 32-बिट समारोह संकेत दिए गए, या इसके विपरीत का उपयोग कर सकते हैं।

कुछ 64-बिट क्रे मशीनें शब्द के निचले 48 बिट्स में int * का प्रतिनिधित्व करती हैं; char * अतिरिक्त रूप से एक शब्द के भीतर बाइट पता इंगित करने के लिए ऊपरी 16 बिट्स का उपयोग करता है।

+0

+1। एफडब्ल्यूआईडब्लू, मुझे लगता है कि आईएसओ सी अब जरूरी है कि स्रोत कोड में 0 का मतलब शून्य सूचक है, अंतर्निहित प्रतिनिधित्व का कोई फर्क नहीं पड़ता। लेकिन यह स्मृति से है और मेरे पास फिलहाल सी 1 एक्स की एक प्रतिलिपि नहीं है। – paxdiablo

+0

बिल्कुल वही जो मैं खोज रहा था। धन्यवाद। –

+5

सी स्रोत कोड में नल मैक्रो अभी भी एक पूर्णांक निरंतर अभिव्यक्ति होगी जो उसके 0 या एक (शून्य *) का मूल्यांकन करता है।परिणामी सूचक मूल्य में एक प्रतिनिधित्व हो सकता है जो 0 नहीं है लेकिन इसका मतलब यह नहीं है कि स्रोत कोड यह मान सकता है कि यह 0xffff या ऐसा कुछ भी होगा। –

2

सी कंपाइलर्स में, यह '((void *)0)' तक विस्तारित हो सकता है (लेकिन ऐसा करने की आवश्यकता नहीं है)। यह सी ++ कंपाइलर्स के लिए काम नहीं करता है।

सी एफएक्यू भी देखें जिसमें null pointers पर एक पूरा अध्याय है।

2

बहुत समय पहले जब इसे ((void*)0) या कुछ अन्य मशीन-विशिष्ट तरीके से टाइप किया गया था, जहां उस मशीन ने सभी शून्य बिट पैटर्न का उपयोग नहीं किया था।

कुछ प्लेटफ़ॉर्म (कुछ सीडीसी या हनीवेल मशीनों) शून्य के लिए एक अलग सा पैटर्न (यानी, नहीं सब शून्य) हालांकि आईएसओ/एएनएसआई तय है कि इससे पहले कि C90 पुष्टि की गई, निर्दिष्ट करने के द्वारा कि 0 में सही शून्य सूचक था अंतर्निहित बिट पैटर्न के पर ध्यान दिए बिना स्रोत कोड, C11 6.3.2.3 Pointers /4 से (हालांकि, के रूप में उल्लेख किया है, यह शब्द वापस C90 तक जाती):

एक पूर्णांक मान 0, या इस तरह के एक अभिव्यक्ति टाइप करने के लिए void * डाली के साथ लगातार अभिव्यक्ति, एक अशक्त सूचक लगातार कहा जाता है।

0

NULL सी में मैक्रो कार्यान्वयन परिभाषित शून्य-सूचक स्थिरांक के लिए विस्तारित करता है। यह कुछ भी हो सकता है (चूंकि यह कार्यान्वयन-परिभाषित है), लेकिन सूचक संदर्भ में प्रभाव हमेशा समान होता है जैसे कि यह स्थिर 0 तक विस्तारित होता है।

वहाँ मानक सी इतिहास में एक समय था जब NULL कुछ विशेष रूप से नहीं 0 करने के लिए विस्तारित कभी नहीं रहा, जब तक आप के रूप में "नहीं 0" (void *) 0 पर विचार करें। लेकिन (void *) 0NULL के लिए इस दिन व्यापक रूप से उपयोग किया जाता है।

+3

_ISO_ सी इतिहास में कभी समय नहीं रहा है ... शुरुआती कंप्यूटर्स के पास अंतर्निहित बिट्स के बावजूद 0 को संहिताबद्ध करने से पहले बहुत अलग पैटर्न थे। हालांकि, मेरे आगे बढ़ने वाले वर्षों को देखते हुए, मुझे याद नहीं आया कि वे कौन से थे :-) – paxdiablo

+0

अध्याय और कविता कृपया? आईएसओ सी मानक स्पष्ट रूप से कहता है कि एनयूएलएल जो कुछ भी कार्यान्वयन करना चाहता है, उसका विस्तार कर सकता है। '4.1.5। सामान्य परिभाषा [...] मैक्रोज़ न्यूल हैं जो कार्यान्वयन-परिभाषित शून्य सूचक स्थिरांक तक फैलता है; और [...] '। इसे अन्य पाठ के साथ भ्रमित नहीं किया जाना चाहिए जो कहता है कि अभिव्यक्ति 0 सूचक प्रकार में कनवर्ट किया गया है जो हमेशा शून्य सूचकांक प्राप्त करने का एक वैध तरीका है। जो कुछ भी करने के लिए नहीं है जो न्यूल विस्तार करता है। – janks

+0

@janks, मुझे लगता है कि @paxdiablo कह रहा है कि सूचकांक संदर्भ में आईएसओ सी, '0' में शून्य सूचक स्थिर है, लेकिन पूर्व-आईएसओ (प्री-एएनएसआई) सी में, यह जरूरी नहीं था। संभवतः उन रूपों में से एक 'नूल' लिखता है, या जो भी जादू संख्या शून्य सूचक होता है। –

2

जीएनयू libio में।एच फ़ाइल:

#ifndef NULL 
# if defined __GNUG__ && \ 
(__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 8)) 
# define NULL (__null) 
# else 
# if !defined(__cplusplus) 
# define NULL ((void*)0) 
# else 
# define NULL (0) 
# endif 
# endif 
#endif 

__cplusplus पर सशर्त संकलन नोट करें। सी ++ का उपयोग नहीं कर सकता ((शून्य *) 0) सूचक कास्टिंग के बारे में इसके कठोर नियमों के कारण; मानक के लिए NULL होना आवश्यक है 0. सी नल की अन्य परिभाषाओं की अनुमति देता है।

0

आधुनिक सी में, void *pointer = 0; किसी भी बिंदु पर इंगित करने के लिए "पॉइंटर" प्रारंभ करने के लिए है। यह मंच-विशिष्ट है कि क्या यह "पॉइंटर" के बिट्स को शून्य से सेट करके पूरा किया जाता है।

अतीत में, एक सूचक संदर्भ में "0" का औपचारिक अर्थ स्थापित नहीं किया गया था। पॉइंटर को वास्तविक मान पर सेट करना आवश्यक था जिसे मंच "कहीं भी इंगित नहीं करता" के रूप में माना जाता था। एक उदाहरण के रूप में, एक प्लेटफॉर्म कुछ निश्चित पता चुन सकता है जिसे कभी भी मैप किए गए पेज को नहीं मिलता है। इस मामले में, एक पुरानी संकलक में, मंच NULL के रूप में परिभाषित हो सकता है:

#define NULL ((void*)0xFFFFF000) 

बेशक, आज, वहाँ ((void*)0) के रूप में यह परिभाषित करने के लिए नहीं कोई कारण नहीं है।

+0

'अतीत में, एक सूचक संदर्भ में "0" का औपचारिक अर्थ स्थापित नहीं किया गया था।' - ठीक है, जहां 'अतीत में' का मतलब है 'सी भाषा के आविष्कार से पहले'। –

+0

@ विन्डोज़: नहीं, यह मामला नहीं है। यह पहले संस्करण के के एंड आर सी के रूप में स्थापित नहीं किया गया था। 'शून्य * पीआरटी = 0; 'परिभाषित अर्थ नहीं था। –

+1

मेरी यादों में से सबसे अच्छे सही होने के लिए, पहले संस्करण में के एंड आर सी के रूप में कोई "शून्य" या "शून्य *" नहीं था। हालांकि, एक सूचक संदर्भ में "0" का औपचारिक अर्थ 1 9 70 में सी की शुरुआत में स्थापित किया गया था। –

0

सी कंपाइलर आमतौर पर ((void *)0) का उपयोग करते हैं। कारण NULL को परिवर्तनीय तर्कों के साथ कार्य करने के लिए गुजर रहा है (या अब दुर्लभ लेकिन अभी भी प्रोटोटाइप के बिना कानूनी कार्य)। जब पॉइंटर्स int से बड़े होते हैं, 0 को केवल int पर प्रचारित किया जाएगा और इस प्रकार पॉइंटर के रूप में सही ढंग से पढ़ा नहीं जाएगा।

सी ++ कंपाइलर उस परिभाषा का उपयोग नहीं कर सकते हैं क्योंकि सी ++ void * से अंतर्निहित कास्ट की अनुमति नहीं देता है (किसी भी पॉइंटर को 0 कास्टिंग विशेषीकृत किया जाता है)। हालांकि सी ++ 11 ने नया कीवर्ड nullptr पेश किया जो कि विशेष nullptr_t का शून्य सूचकांक निरंतर किसी भी सूचक प्रकार के लिए परिवर्तनीय रूप से परिवर्तनीय है, लेकिन संख्या नहीं है। यह अतिमानवी तर्क तर्क और अंतर्निहित कास्ट और अतिरिक्त कारणों के साथ अतिरिक्त रूप से अधिक गंभीर समस्याएं हल करता है (0 स्पष्ट कारण के लिए int पॉइंटर पर अधिभार का चयन करता है)। पुराने कंपेलरों के लिए इन्हें स्वयं परिभाषित करना कानूनी है और कुछ सी ++ कंपाइलर्स ने अतीत में कोशिश की थी।

संबंधित मुद्दे