2010-03-03 15 views
8

संभव डुप्लिकेट:
Could anyone explain these undefined behaviors (i = i++ + ++i , i = i++, etc…)x = x ++ +++ x का मूल्यांकन आदेश क्या होगा; हो सकता है?

जावा में मूल्यांकन के क्रम बाएँ-से-सही होने के लिए निर्दिष्ट किया जाता है। क्या यह सी और सी ++ के मामले में भी है, या क्या यह कार्यान्वयन निर्भर है? मुझे याद है कि मूल्यांकन आदेश फ़ंक्शन तर्कों के लिए निर्दिष्ट नहीं है, लेकिन उप-अभिव्यक्तियों के बारे में क्या है?

+0

डुप्लिकेट्स: http://stackoverflow.com/questions/949433/could-anyone-explain-these-undefined-behaviors-iiiii-etc http://stackoverflow.com/questions/1826414/whats-the-value- ऑफ-आईआई-बंद http://stackoverflow.com/questions/1788696/how-the-code-behaves- अलग-for-java-and-c-compiler – bk1e

+18

lol। मॉड मोड ने अपना खुद का प्रश्न बंद कर दिया: डी – Earlz

+3

@ बीके 1e: लिंक के लिए धन्यवाद। मुझे लगा कि यह पहले यहां कवर किया जाएगा, लेकिन जब मैंने सवाल पूछा तो यह नहीं आया। मुझे लगता है कि मूल खोजने के लिए सबसे तेज़ तरीका सिर्फ पूछना होगा। :) –

उत्तर

13

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

यहाँ आप एक बीच के अनुक्रम बिंदु के बिना xतीन बार संशोधित कर रहे हैं, तो आप आरक्षण बंद अच्छी तरह से कर रहे हैं;)


C99 मानक के प्रासंगिक हिस्सा है "6.5 भाव":

पिछले और अगले अनुक्रम बिंदु एक वस्तु अपने संग्रहीत एक के मूल्यांकन से एक बार ज्यादा से ज्यादा संशोधित मूल्य होगा बीच 2 एन अभिव्यक्ति। इसके अलावा, पूर्व मान केवल संग्रहीत मान निर्धारित करने के लिए पढ़ा जाएगा।

और

3 ऑपरेटरों और ऑपरेंड के समूहीकरण वाक्य रचना से मिलता है। के रूप में बाद में निर्दिष्ट छोड़कर (? समारोह-कॉल(), & &, || के लिए: और अल्पविराम ऑपरेटर), subexpressions की मूल्यांकन के आदेश और जिस क्रम में साइड इफेक्ट जगह ले दोनों अनिर्दिष्ट हैं ।


यह कानूनी कोड है कि मूल्यांकन के अनिर्दिष्ट आदेश को दर्शाता है लिखने के लिए संभव है - उदाहरण के लिए:

#include <stdio.h> 

int foo(void) 
{ 
    puts("foo"); 
    return 1; 
} 

int bar(void) 
{ 
    puts("bar"); 
    return 2; 
} 

int main() 
{ 
    int x; 

    x = foo() + bar(); 
    putchar('\n'); 

    return x; 
} 

(यह है कि क्या आप foobar या barfoo के उत्पादन में मिल अनिर्दिष्ट है)।

+0

त्वरित उत्तर के लिए धन्यवाद। –

2

सी मानक गारंटी नहीं देता है कि पूर्व-वृद्धि के बाद पोस्ट-वृद्धि वास्तव में "घटित" होगी। तो यह अपरिभाषित व्यवहार है।

1

यह वैध सी कथन नहीं है, इसलिए मूल्यांकन आदेश के बारे में बात करना समझ में नहीं आता है।

+1

"वैध" से आपका क्या मतलब है? यह सफलतापूर्वक जीसीसी और जी ++ में संकलित करता है। –

+4

जीसीसी द्वारा फ़ाइल को सफलतापूर्वक संकलित किया गया है या नहीं, इसमें वैध सी कथन शामिल हैं या नहीं, इसके साथ कुछ लेना देना नहीं है। सी मानक निर्धारित करता है कि वैध सी क्या है, एक संकलक नहीं। –

+4

यह कथन वाक्य रचनात्मक रूप से मान्य है, हालांकि अर्थात् गलत है क्योंकि यह अपरिभाषित व्यवहार का कारण बनता है। – qrdl

3

सी ++ 03 मानक 5।4

छोड़कर जहां बताया गया है, अलग-अलग ऑपरेटरों और व्यक्तिगत अभिव्यक्ति के subexpressions की ऑपरेंड के मूल्यांकन, और आदेश जिसमें साइड इफेक्ट जगह लेने के आदेश, unspecified.53) पिछले के बीच है और अगली अनुक्रम बिंदु एक स्केलर ऑब्जेक्ट का संग्रहित मूल्य एक बार अभिव्यक्ति के मूल्यांकन द्वारा संशोधित किया जाएगा। इसके अलावा, पूर्व मान संग्रहीत करने के लिए केवल मान निर्धारित करने के लिए उपयोग किया जाएगा। पैराग्राफ की आवश्यकताओं को पूर्ण अभिव्यक्ति के उप-अभिव्यक्तियों के स्वीकार्य क्रम के लिए पूरा किया जाएगा; अन्यथा व्यवहार अपरिभाषित है।

... इसलिए, अपरिभाषित और कार्यान्वयन निर्भर है।

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