2015-12-15 6 views
9

वहाँ दो संबंधित सी मानक नियम हैं:`uintptr_t` और उपाध्यक्ष प्रतिकूल करने के लिए एक गैर `void` सूचक परिवर्तित

C99 मानक, 6.3.2.3:

एक सूचक शून्य करने के लिए बदला जा सकता है या किसी सूचक से किसी भी अपूर्ण या ऑब्जेक्ट प्रकार से। किसी अपूर्ण या ऑब्जेक्ट प्रकार को पॉइंटर को पॉइंटर में शून्य और फिर से परिवर्तित करने के लिए परिवर्तित किया जा सकता है; परिणाम मूल सूचक के बराबर की तुलना करेगा।

और 7.20.1.4:

निम्न प्रकार संपत्ति है कि किसी भी वैध सूचक शून्य करने के लिए इस प्रकार के लिए परिवर्तित किया जा सकता है के साथ एक अहस्ताक्षरित पूर्णांक प्रकार निर्दिष्ट करता, फिर वापस सूचक शून्य करने के लिए करने के लिए परिवर्तित, और परिणाम मूल सूचक के बराबर की तुलना करेंगे: uintptr_t

इसका मतलब है, कि followin जी कोड अनुपालन है:

int *p = NULL; 
void *q = (void*)p; 
uintptr_t s = (uintptr_t)q; 

लेकिन क्या इसे वास्तव में दो-चरणीय कलाकारों की आवश्यकता है?

int *p = NULL; 
uintptr_t s = (uintptr_t)p; 

(ठीक है, यह शायद सबसे compilers पर है, लेकिन मेरे सवाल का मानक अनुपालन के बारे में है जाएगा)

+0

ध्यान दें कि 'पी' दोनों में अनियमित है। शायद कुछ ऐसा: 'int i = 42; int * पी = और मैं; ... 'इसे ठीक कर देगा। –

+0

@ l3x अच्छी तरह से, हाँ, धन्यवाद। पूर्णता के लिए इसे ठीक कर देगा। –

उत्तर

7

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

लेखन uintptr_t s = (uintptr_t)(void*)p; आपके कोड के पाठक को सिग्नल जो आप जानते हैं कि आप क्या कर रहे हैं।

+3

ईमानदारी से, अगर मैंने उस कोड को देखा, तो मैं सवाल करूँगा कि क्या लेखक जानता था कि वे क्या कर रहे थे। आंशिक रूप से क्योंकि मेरे पास मानक से प्रासंगिक मार्गों की पूर्ण याद नहीं होगी। मैं यह नहीं कह रहा हूं कि इसे लिखना गलत है, लेकिन यह मुझे स्पष्ट रूप से सही रूप से सही नहीं करेगा। –

+2

किस मामले में, एक टिप्पणी लिखने में कोई नुकसान नहीं होगा। आपके घर की नीतियों पर निर्भर करता है। – Bathsheba

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