2012-06-18 9 views
7

में पोस्टिनक्रिएशन मैं इस धारणा के तहत था कि पोस्टिनक्रिकमेंट (या प्रीइंक्रिकमेंट) केवल दाहिने हाथ (=) के दायीं तरफ किया जा सकता है। लेकिन मैं कोड के टुकड़े नीचे संकलित करने में सक्षम हूँ। क्या आप इस विशिष्ट कोड को विशेष रूप से नीचे पंक्ति में समझने में मेरी सहायता कर सकते हैं। स्रोत: http://www.ibm.com/developerworks/library/pa-dalign/बाएं तरफ

*data8++ = -*data8; 


void Munge8(void *data, uint32_t size) { 
    uint8_t *data8 = (uint8_t*) data; 
    uint8_t *data8End = data8 + size; 

    while(data8 != data8End) { 
     *data8++ = -*data8; 
    } 
} 
+0

असाइन '- *' * data8' तो बढ़ा देते 'को data8' data8' - प्रभावी ढंग से negating' size' 'डेटा' – Erik

उत्तर

3

आपका इंप्रेशन गलत है, मुझे लगता है। आप निश्चित रूप से की तरह कर सकते हैं:

*a++ = *b++; 

वास्तव में, कि अक्सर strcpy कैसे कार्यान्वित किया जाता है है। तुम भी सब पर एक = बिना पोस्ट या पूर्व वृद्धि कर सकते हैं:

a++; 
+0

प्रतीक्षा में बाइट्स, तो मैं समझौते में था आपकी मूल पोस्ट के साथ। यह अपरिभाषित व्यवहार कैसे नहीं है? –

+0

स्ट्रैपी इस तरह लागू नहीं किया गया है। आप पहले डेटा के बड़े हिस्सों के बिट पैटर्न में स्ट्रिंग के अंत की तलाश करते हैं, फिर डेटा को बड़े हिस्सों में कॉपी करें (आमतौर पर 64 बिट)। –

+0

@ शार्थ: हालांकि यह कैसे अपरिभाषित है? मैं एक मानक जंकी नहीं हूं, लेकिन आरएचएस का मूल्यांकन पहले और फिर एलएचएस किया जाना चाहिए। इस प्रकार कोई समस्या नहीं होनी चाहिए। –

1

कोई कारण नहीं है के बाद वेतन वृद्धि असाइनमेंट ऑपरेटर के बाएं हाथ की ओर पर नहीं किया जा सकता है। एक पोस्ट-इंक्रिमेंट ऑपरेटर बस अपने पिछले राज्य में ऑब्जेक्ट की अस्थायी प्रतिलिपि देता है, और उस अस्थायी वस्तु (इस मामले में एक पॉइंटर) पर ऑपरेशन हो सकता है।

अब, के मामले में:

*data8++ = -*data8; 
ऑपरेटर आदेश की वजह से

, data8 सूचक के बाद पहले वृद्धि की जाती, हो जाएगा पिछले सूचक मूल्य की एक प्रति लौटने। उस पिछले सूचक मूल्य को फिर से संदर्भित किया जाएगा और असाइनमेंट ऑपरेटर के दाईं ओर अभिव्यक्ति के परिणाम असाइन किए जाएंगे।

संपादित करें: के रूप में अन्य लोगों ने बताया है, तो आप एक बार जबकि एक दृश्य बिंदु के बिना कि स्मृति स्थान के लिए लिख से ज्यादा पढ़कर data8 की सामग्री को संशोधित कर रहे हैं, तो यह अपरिभाषित व्यवहार है।

+0

यह कैसे अनिर्धारित है? ऐसा लगता है कि 'x = -x' अनिर्धारित है। –

+0

आप 'data8' (यानी सूचक मूल्य स्वयं) की सामग्री को संशोधित कर रहे हैं और फिर इसे अनुक्रम बिंदु के बिना दो अलग-अलग स्थानों में वापस पढ़ रहे हैं। जैसा कि अन्य ने इंगित किया है, यदि एलएचएस या आरएचएस का मूल्यांकन पहले किया जाता है तो आपको दो अलग-अलग परिणाम मिलेंगे ... इस प्रकार "अपरिभाषित व्यवहार" क्योंकि सी-मानक परिभाषित नहीं करता है कि किस पक्ष को पहले मूल्यांकन किया जाना चाहिए ... उदाहरण के लिए, एलएचएस और आरएचएस के मूल्यांकन interleaved किया जा सकता है!आपके उदाहरण में, एक स्पष्ट मूल्यांकन आदेश है क्योंकि एलएचएस 'x' के मान को नहीं पढ़ रहा है, यह सिर्फ इसे लिख रहा है। तो केवल एक ही पढ़ा/लिखना है। – Jason

+0

हाँ। मैं एक बहाना के रूप में नींद की कमी का दावा करेंगे। –

2

++ पॉइंटर पर लागू होता है, न कि data8 द्वारा निर्धारित मूल्य के लिए।

*data8 = -*data8; 
data8++; 

संपादित करें:

*data8++ = -*data8;

के बराबर है
C99 standard 6.5 और Annex C पढ़ने के बाद, यह स्पष्ट है = एक दृश्य बिंदु नहीं है। मानक केवल &&, ||, , और ? का उल्लेख करता है।

, के बाद से data8= के दोनों ओर जो कोई अनुक्रम बिंदु और मानक जनादेश नहीं पड़ता कि आरएचएस पहले मूल्यांकन किया जाना चाहिए या फिर एलएचएस पहले मूल्यांकन किया जाना चाहिए पर संशोधित किया गया है, मुझे विश्वास है इस अपरिभाषित व्यवहार है हूँ।

Any good reason why assignment operator isn't a sequence point?

यह ऊपर पोस्ट = एक दृश्य बिंदु नहीं किया जा रहा है और काफी यहाँ संबंधित है चर्चा।

+0

'डेटा 8' असाइनमेंट ऑपरेटर के दोनों किनारों पर संशोधित नहीं है, बल्कि यह एलएचएस पर संशोधित है, लेकिन इसे दो बार पढ़ा जाता है जिसमें कोई अनुक्रम बिंदु नहीं है यह निर्धारित करता है कि पाठ को लिखने के खिलाफ अनुक्रमित किया गया है। – Jason

+0

@ जेसन आप सही हैं। '=' अनुक्रम बिंदु नहीं है यहां कुंजी है। –

7

तो, मुझे पूरा यकीन है कि यह अपरिभाषित व्यवहार है।कोई अनुक्रम में अंतिम अर्धविराम के अलावा अन्य बिंदु है:

*(0x20) = -*(0x20); 

या

*(0x20) = -*(0x24); 

क्योंकि कोई:

*data8++ = -*data8; 

तो data8 0x20 के बराबर है, को यह बराबर है इस निर्णय को करने का तरीका, (क्योंकि आपने इसे दो बार पढ़ने के दौरान एक चर को संपादित किया है, बिना किसी अंतराल अनुक्रम बिंदु के), यह अपरिभाषित व्यवहार है।


हम इस बात के बारे में बात कर सकते हैं कि कोड का निम्न भाग क्या करता है। जो उपर्युक्त कोड द्वारा लक्षित किया गया है।

while(data8 != data8End) { 
    *data8 = -*data8; 
    data8++; 
} 

आप यहां क्या कर रहे हैं उम्मीद है कि यह अधिक सरल है। आप अपना इनपुट सरणी ले रहे हैं, और इसे देख रहे हैं, इसलिए यह 8 बिट संख्याओं की एक श्रृंखला है। फिर, जगह में, आप प्रत्येक को अस्वीकार करते हैं।

+0

मुझे लगता है कि आप यहां "चर" को भ्रमित कर रहे हैं। पॉइंटर का मूल्य और मूल्य सूचक सूचक पर संग्रहीत मूल्य दो अलग-अलग चीजें हैं। इस मामले में किसी ने इसे दो बार पढ़ने के दौरान एक चर संपादित किया है। "डेटा 8" द्वारा पता सूचक पर मूल्य आरएचएस पर एक बार पढ़ा जाता है। यह एक बार वापस लिखा है। एलएचएस पर पॉइंटर बदल जाता है। –

+0

या शायद मैं करता हूं। हेहे –

+2

@Vlad, एक '=' अनुक्रम बिंदु नहीं है। –

0

मुझे लगता है कि

* data8 ++ = - * data8;

को

* data8 बराबर है = - * (data8 +1);

data8 = data8 +1

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