सी ++ 11 मानक का कहना है:
5,17/1: असाइनमेंट ऑपरेटर (=) और मिश्रित असाइनमेंट ऑपरेटर सभी समूह सही-से-बाएँ। (...) असाइनमेंट दाएं और बाएं ऑपरेटरों की मान गणना के बाद अनुक्रमित है, और असाइनमेंट अभिव्यक्ति की मान गणना से पहले।
1,9/15: एक अदिश वस्तु पर एक पक्ष प्रभाव एक ही अदिश वस्तु या एक मूल्य गणना एक ही अदिश वस्तु के मूल्य का उपयोग करने पर या तो एक और पक्ष प्रभाव को unsequenced रिश्तेदार है, तो व्यवहार अपरिभाषित है ।
*a
और *b
गणना कर रहे हैं: इस प्रकार
तो *a ^= *b
अनुक्रम है। यह नहीं निर्धारित जो क्रम में
XOR आपरेशन
किया जाता है काम किया जाता है, यानी नया मान *a
में संग्रहित है नया मान अभिव्यक्ति के परिणाम के रूप में प्रयोग किया जाता है (*a ^= *b)
अब *b ^= *a ^= *b
, जो प्राथमिकता नियम के अनुसार *b ^= (*a ^= *b)
है:
*b
और (*a ^= *b)
की गणना की जाती है। यह किस क्रम में निर्धारित है। लेकिन *b
(*a ^= *b)
द्वारा संशोधित नहीं किया गया है, इससे कोई फर्क नहीं पड़ता।
- XOR आपरेशन
- काम किया जाता है, यानी नया मान
*a ^= *b ^= *a ^= *b
साथ अनिर्दिष्ट अनुक्रमण को *b
में संग्रहित है लेकिन अब जो प्राथमिकता नियमों *a ^= (*b ^= (*a ^= *b))
के अनुसार है किया जाता है:
*a
और (*b ^= (*a ^= *b))
की गणना की जाती है। यह किस क्रम में निर्धारित है। लेकिन *a
के रूप में (*b ^= (*a ^= *b))
द्वारा संशोधित किया गया है। तो परिणाम इस बात पर निर्भर करेगा कि किस मूल्य की गणना पहले की जाती है। यह स्पष्ट रूप से एक यूबी है।
मान लीजिए *a
पहले मूल्यांकन किया जाता है, (यानी पहले कुछ और):
आप जो (*b ^= (*a ^= *b))
के मूल्य के साथ xored किया जाएगा इसके बारे में मूल मान, मिलेगा, जो कि मूल *b
है मूल के साथ xored *a
*b
के साथ फिर से xored। इसके परिणामस्वरूप 0 (जिसे *a
में संग्रहीत किया जाएगा)।
मान लीजिए (*b ^= (*a ^= *b))
मूल्यांकन किया जाता है पहले, तो उसके परिणाम मूल *a
है, लेकिन *a
की सामग्री के मूल *a
मूल *b
साथ xored करने के लिए बदल गया है। इस प्रकार इस मूल *b
(जो *a
में संग्रहीत किया जाएगा)
वैसे में परिणाम होगा, दोनों ही मामलों में, *b
*a
के मूल मूल्य *b
अर्थ है कि *b
मूल *a
शामिल होंगे साथ दो बार xored शामिल हैं।
निष्कर्ष: यहाँ प्रदर्शित किया गया है कि *b
के अंतिम मूल्य विशिष्ट इस अभिव्यक्ति से निर्धारित होता है, लेकिन वह *a
के अंतिम मूल्य विशिष्ट परिभाषित नहीं है (दो मानों संभव हो)। तो यह स्पष्ट रूप से अनसुलझा/संशोधित परिणाम है! यह आपके कंपाइलर के आधार पर स्वैप हो सकता है या *a
खो सकता है।
सुनिश्चित करने के लिए स्वैपिंग कैसे करें?
मैंने ऊपर दिखाया है कि पहले दो यौगिक असाइनमेंट अच्छी तरह से निर्दिष्ट हैं। इसलिए हमें यह सुनिश्चित करना है कि आखिरी यौगिक असाइनमेंट उसके बाद किया जाता है।
5,18/1: यह एक अल्पविराम ऑपरेटर द्वारा गारंटी दी जा सकती अल्पविराम से अलग भाव की एक जोड़ी मूल्यांकन किया जाता है बाएँ-से-दाएँ और बाएँ अभिव्यक्ति के मूल्य
त्याग दिया जाता है
इसलिए, निम्नलिखित काम करेगा:
void safe_swap(int* a, int* b) {
if (a != b)
*b ^= *a ^= *b, *a ^= *b;
}
मैं यहाँ के बारे में इस C11 में नए अनुक्रमण शासन के साथ की अनुमति है या एक चर्चा याद है। सी 99 में, यह स्पष्ट रूप से अपरिभाषित है ('* ए' को अनुक्रम बिंदु के बिना दो बार संशोधित किया गया है)। – mafso
मुझे याद है कि सी ++ अपने असाइनमेंट ऑपरेटरों पर कुछ अतिरिक्त अनुक्रमिक गारंटी देता है, क्योंकि सी असाइनमेंट ऑपरेटर मूल्य वापस कर देते हैं, लेकिन सी ++ असाइनमेंट ऑपरेटर अंतराल लौटाते हैं, और बाद के अंतराल से लेकर रावल्यू रूपांतरण में अच्छी तरह से परिभाषित व्यवहार होना चाहिए। नतीजा * हो सकता है कि यह सी ++ में मान्य है, लेकिन मुझे यकीन नहीं है। – hvd
@ एचवीडी: सी 11 ने थ्रेडिंग मानकीकरण के कारण सी ++ अनुक्रमण मॉडल अपनाया। एक असाइनमेंट के एलएचएस का संशोधन अब एलएचएस और आरएचएस के मूल्यांकन के बाद अनुक्रमित किया गया है। – mafso