2012-01-13 7 views
12

मैं कोड के इस नमूना टुकड़े के बारे में सोच रहा हूँ:है `* - में p` वास्तव में कानूनी (अच्छी तरह का गठन) सी ++ 03

int main() 
{ 
    char *p ; 
    char arr[100] = "Hello"; 
    if ((p=arr)[0] == 'H') // do stuffs 
} 

इस कोड को वास्तव में अच्छी तरह से सी ++ 03 में गठन किया गया है ?

मेरे तर्क यह है कि = के पक्ष प्रभाव केवल अगले अनुक्रम बिंदु के बाद पूरा हो गया है और तब से हम कोड अच्छी तरह से गठन नहीं किया जा सकता है p=arr का परिणाम तक पहुँच रहे हैं, वहाँ = और [] संचालन के बीच कोई आदेश है।

क्या मैं सही हूँ?

व्यवहार सी और सी ++ 11 में अच्छी तरह से परिभाषित किया गया है। यह कोड वास्तव में MySQL से लिया गया है।

+19

शीर्षक में कोड आपके द्वारा दिए गए कोड नमूने में प्रकट नहीं होता है। – porges

+3

'((ए = बी) + एक्स) 'अच्छी तरह परिभाषित है? यदि यह अच्छी तरह से परिभाषित किया गया है, तो '(पी = एआर) [0]' अच्छी तरह से परिभाषित किया जाएगा, क्योंकि यह '* ((पी = एआर) + 0) के बराबर है ' – Nawaz

+1

@P्रासून: आपके अनुसार तर्क, 'int x = ++ i + n' यूबी का आह्वान करता है? क्योंकि आपके अनुसार, कारण होना चाहिए: '++' का दुष्प्रभाव केवल अगले अनुक्रम बिंदु के बाद पूरा हो गया है और चूंकि हम '++ i' के परिणाम तक पहुंच रहे हैं, इसलिए कोड अच्छी तरह से गठित नहीं किया जा सकता है। क्या यह? – Nawaz

उत्तर

24

बेशक यह अच्छी तरह से परिभाषित है।

इससे कोई फर्क नहीं पड़ता कि असाइनमेंट p=arr कब होता है। आप p[0] का मूल्यांकन नहीं कर रहे हैं, आप (p=arr) के परिणाम को सब्सक्राइब कर रहे हैं, जो पॉइंटर मान है जिसे p में संग्रहीत किया जा रहा है। चाहे इसे संग्रहीत किया गया हो या नहीं, फिर भी मूल्य नहीं बदलता है, और मूल्य p को अभी तक संशोधित किया गया है या नहीं, भले ही मूल्य ज्ञात हो।

इसी प्रकार, *--p में, कोई अपरिभाषित व्यवहार नहीं है। अनुक्रम बिंदुओं के बीच कम से कम एक लिख सहित, एक ही चर को दो बार एक्सेस किया गया था, तो केवल अपरिभाषित व्यवहार होगा। लेकिन p को केवल --p के हिस्से के रूप में उपयोग किया जाता है। इसे फिर से नहीं पढ़ा जाता है (*p), dereferencing ऑपरेटर --p के परिणाम पर लागू होता है जो एक अच्छी तरह से परिभाषित सूचक मान है। ,

void* a; 
void* p = &a; 
reinterpret_cast<void**>(p = &p)[0] = 0; 

होगा के रूप में

int *pi = new int[5]; 
int i = **&++pi; 

यह स्पष्ट किया जाना चाहिए कि एक preincrement का परिणाम एक पढ़ा लिखने के साथ अव्यवस्थित नहीं है:

अब, यह अपरिभाषित व्यवहार किया जाएगा क्योंकि यह कहने के लिए कि एक दौड़ है कि ++p कभी भी एक रावल्यू के रूप में उपयोग नहीं किया जा सकता है, इस मामले में इसे अनुक्रम बिंदुओं के बीच अकेले खड़े रहना चाहिए, और बाद में वृद्धि के लिए इंस्टी का उपयोग किया जा सकता है विज्ञापन। भाषा में पूर्व वृद्धि और वृद्धि के बाद दोनों का कोई फायदा नहीं होगा।

+2

भविष्य के पाठकों के लिए, कृपया इस मेटा पोस्ट को देखें: http://meta.stackexchange.com/questions/118996/where-did -ल-द-टिप्पणियां-go-on-is-p-वास्तव में-कानूनी-गठित-इन-सी03 – Mysticial

+1

इसके अलावा, हटाए गए टिप्पणियों की एक प्रतिलिपि यहां पाई जा सकती है: http://i.stack.imgur.com/ f4rIE.png –

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