2013-04-20 11 views
5

द्वारा पूर्वनिर्धारित नहीं किया गया है इस समस्या ने मुझे थोड़ी देर तक परेशान किया। मैं शून्य का एक अलग परिभाषा कभी नहीं देखा था, यह हमेशा हैक्यों एनयूएलएल को संकलक

#define NULL ((void *) 0) 

वहाँ किसी भी वास्तुकला जहां शून्य diferently परिभाषित किया गया है है, और यदि हां, तो क्यों संकलक हमारे लिए इस की घोषणा नहीं करते हैं?

+0

आप 'NULL' के बजाय' 0' का उपयोग कर सकते हैं। – pmg

+0

NULL को 'stddef.h' में परिभाषित किया गया है, आपको इसे स्वयं परिभाषित करने की आवश्यकता नहीं है। – Mat

+0

@pmg 0 पोर्टेबल नहीं है अगर मेरे पहले प्रश्न का उत्तर सत्य है – stdcall

उत्तर

3

सी 2011 मानक, online draft

6.3.2.3 प्वाइंटर
...
3 एक पूर्णांक मान 0, या इस तरह के एक अभिव्यक्ति टाइप करने के लिए void * डाली के साथ लगातार अभिव्यक्ति, कहा जाता है शून्य सूचक स्थिर66) यदि कोई शून्य सूचक स्थिर सूचक प्रकार में परिवर्तित हो जाता है, परिणामी सूचक, जिसे शून्य सूचक कहा जाता है, किसी ऑब्जेक्ट या फ़ंक्शन पर किसी सूचक को असमान की तुलना करने की गारंटी दी जाती है।
66) मैक्रो NULL<stddef.h> (और अन्य शीर्षलेख) में एक शून्य सूचक स्थिरांक के रूप में defed है; 7.1 9 देखें।

मैक्रोNULLहमेशा एक शून्य मूल्यवान निरंतर अभिव्यक्ति के रूप में परिभाषित किया गया है; यह एक नग्न 0, या void * को 0 डाली, या कुछ अन्य अभिन्न अभिव्यक्ति है कि जहां तक ​​आपके स्रोत कोड के रूप संबंध है 0 पर मूल्यांकन करता है हो सकता है, NULL हमेशा 0.

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

0

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

इसलिए भाषा स्तर पर इसे परिभाषित करने का कोई कारण नहीं है - यह केवल एक विशेष सूचक मूल्य है जिसे कई कार्यों द्वारा वापस किया जा सकता है।

1

एएनएसआई-सी से पहले अंधेरे युग में पुराने के & आर सी में हार्डवेयर पर कई अलग-अलग कार्यान्वयन थे जिन्हें आज विचित्र माना जाएगा। यह वीएम के दिनों से पहले था जब मशीनें बहुत "वास्तविक" थीं। शून्य के पते न केवल इन मशीनों पर ठीक थे, शून्य का पता लोकप्रिय हो सकता है ... मुझे लगता है कि यह सीडीसी था जो कभी-कभी सिस्टम को निरंतर शून्य पर शून्य पर संग्रहीत करता था (और अजीब चीजें होती हैं अगर यह शून्य-शून्य सेट होती है)।

 if (NULL != ptr)  /* like this */ 
if (ptr)    /* never like this */

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

4

WhozCraig ने इन टिप्पणियों को अब हटाए गए answer पर लिखा है, लेकिन इसे पूर्ण उत्तर में प्रचारित किया जा सकता है (और यही वह है जो मैंने यहां किया है)। वह लिखते हैं:

दिलचस्प ध्यान दें: AS/400, जहां किसी भी गैर वैध सूचक NULL के समकक्ष माना जाता है एक बहुत ही अनूठा मंच है। यह करने के लिए वे जो मैकेनिक्स नियोजित करते हैं वे बस आश्चर्यजनक होते हैं। इस अर्थ में "मान्य" कोई 128-बिट पॉइंटर है (प्लेटफार्म सब कुछ के लिए 128 बिट रैखिक पता स्थान का उपयोग करता है) जिसमें ज्ञात-विश्वसनीय निर्देश सेट द्वारा प्राप्त "मान" होता है। यह विश्वास करना मुश्किल है, int *p = (int *)1; if (p) { printf("foo"); } उस प्लेटफ़ॉर्म पर "foo" प्रिंट नहीं करेगा। पी को असाइन किया गया मान स्रोत-भरोसेमंद नहीं है, और इस प्रकार, "अमान्य" माना जाता है और इस प्रकार NULL के बराबर होता है।

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


यह चिह्नित है समुदाय विकी (यह मेरा जवाब नहीं है - मैं क्रेडिट नहीं मिलना चाहिए), लेकिन इसे नष्ट कर दिया जा सकता है अगर WhozCraig अपने ही जवाब लिखता है।

यह दिखाता है कि दिलचस्प पॉइंटर गुणों के साथ वास्तविक प्लेटफॉर्म हैं।

ऐसे प्लेटफॉर्म हैं जहां #define NULL ((void *)0) सामान्य परिभाषा नहीं है; कुछ प्लेटफार्मों पर यह 0 हो सकता है, अन्य पर 0L या 0ULL या अन्य उचित मूल्य जब तक संकलक इसे समझता है। सी ++ को परिभाषा के रूप में ((void *)0) पसंद नहीं है; सिस्टम जहां सीडर + के साथ हेडर इंटरैक्ट करते हैं, वे शून्य सूचक संस्करण का उपयोग नहीं कर सकते हैं।

मैं एक मशीन जहां एक दिया स्मृति स्थान के लिए char * पते के लिए प्रतिनिधित्व एक ही स्मृति स्थान के लिए int * पते से अलग था पर सी सीखा है। यह void * से पहले के दिनों में था, लेकिन इसका मतलब था कि आपको malloc() उचित रूप से घोषित किया गया था (char *malloc(); - कोई प्रोटोटाइप नहीं), और आपको स्पष्ट रूप से वापसी प्रकार को सही प्रकार पर डालना पड़ा या आपको कोर डंप मिला। सी मानक के लिए आभारी रहें (हालांकि मशीन में सवाल, आईसीएल Perq - तीन नदियों से खराब हार्डवेयर - मानक को परिभाषित किए जाने के समय काफी हद तक अलग किया गया था)। एक

+2

मुझे इस रहने के साथ कोई समस्या नहीं है। ओएस/400 के लिए कोड लिखने के बाद से नौ साल हो गए हैं, और सभी के लिए मुझे पता है कि तब से यह तब से बदल गया है, लेकिन यह इस तरह का एक अविश्वसनीय रूप से अद्वितीय परिप्रेक्ष्य था कि उन्होंने इसे कैसे पूरा किया, मैं उम्मीद करता हूं कि यह अभी भी सटीक होने के लिए स्मृति के लिए पर्याप्त प्रतिबद्ध है प्राइम टाइम के लिए पर्याप्त है। केवल एक "डीएलएल" समारोह का आह्वान निकट-मनोरंजक था, क्योंकि इसे शाब्दिक रूप से सिस्टम नौकरी के रूप में निर्धारित किया जाता है। वह मंच सिर्फ * अद्भुत * है। – WhozCraig

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