2010-04-02 9 views
5

लिनक्स के stddef.h परिभाषित करता है offsetof() के रूप में:क्यों offsetof में नल पॉइंटर घटाना()?

#define offsetof(st, m) \ 
    ((size_t) ((char *)&((st *)(0))->m - (char *)0)) 

क्यों विकिपीडिया संस्करण में (char *)0 घटाना:

#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) 

जबकि offsetof() (http://en.wikipedia.org/wiki/Offsetof) पर विकिपीडिया लेख के रूप में परिभाषित? क्या कोई ऐसा मामला है जहां वास्तव में कोई फर्क पड़ता है?

+0

आप उपयोग नहीं करना चाहिए/अध्ययन कोड कि अपरिभाषित व्यवहार आह्वान कर सकते हैं, इसके बाद के संस्करण की तरह। एक कार्यान्वयन ऐसे skanky हैक्स उपयोग करें, क्योंकि वे जानते हैं कि अपरिभाषित व्यवहार के प्रकार गुप्त रूप से काम कर सकते हैं। लेकिन क्या "गुप्त रूप से काम करता है" पूरी तरह से पोर्टेबल नहीं है। – CTMacUser

उत्तर

6

पहला संस्करण एक डाली है, जो पोर्टेबल नहीं है के साथ एक पूर्णांक में एक सूचक धर्मान्तरित है।

दूसरा संस्करण कंपाइलरों की एक विस्तृत विविधता में अधिक पोर्टेबल है, क्योंकि यह एक टाइपकास्ट के बजाय एक पूर्णांक परिणाम प्राप्त करने के लिए संकलक द्वारा पॉइंटर अंकगणित पर निर्भर करता है।

Btw, मैं संपादक है कि विकी प्रविष्टि है, जो लिनक्स रूप था करने के लिए मूल कोड जोड़ा था। बाद में संपादकों ने इसे अधिक पोर्टेबल संस्करण में बदल दिया।

+0

प्रतिक्रिया के लिए धन्यवाद। फॉलोअप सवाल "(size_t) ((चार *) 0) कभी 0 तक आकलन नहीं करता है?" http://stackoverflow.com/questions/2581522/does-size-tchar-0-ever-not-evaluate-to-0 –

+0

पर पोस्ट किया गया दिलचस्प है - लेकिन दूसरी अभिव्यक्ति वास्तव में कोई और पोर्टेबल है, क्योंकि पॉइंटर अंकगणित शून्य पॉइंटर्स पर अपरिभाषित है? –

+1

यह इस अर्थ में अधिक पोर्टेबल है कि यह अधिक CPUs पर काम करता है। अपरिभाषित (मानक द्वारा) का मतलब यह नहीं है कि यह कुछ विशिष्ट वास्तुकलाओं के लिए काम नहीं कर सकता है। –

4

मानक बिट पैटर्न को 0 पर मूल्यांकन करने के लिए शून्य सूचक की आवश्यकता नहीं है, लेकिन एक मंच विशिष्ट मूल्य के मूल्यांकन कर सकते हैं।

घटाव कर की गारंटी देता है जब एक पूर्णांक मूल्य में परिवर्तित, शून्य 0.

+2

यही कारण नहीं है; '0' के अलावा किसी भी उचित स्थिरता का भी उपयोग किया जा सकता है। नीचे मेरा जवाब देखें। –