2012-03-22 18 views
7

मैं सिर्फ एक व्यवहार जो मुझे हैरान कर दिया पर ठोकर खाई त्रुटियों के बिना संकलित करता है। उपर्युक्त मामले में एक्स 1 बाद में है। ध्यान दें कि पिछली घोषणा द्वारा दायरे में कोई चर एक्स नहीं है।प्रारंभ में हाल में घोषित चर का उपयोग करना (int x = x + 1)?</p> <p>जब लेखन:: - कार्यक्रम (या और भी जटिल अभिव्यक्ति को शामिल नव निर्मित चर x) मेरी जीसीसी/जी ++</p> <pre><code>int x = x+1; </code></pre> एक सी में/C++ <p>

तो मुझे पता है कि यह सही व्यवहार मेरी जीसीसी संस्करण या सामान्य रूप में जीसीसी के साथ या सिर्फ एक पार्सर pecularity (कुछ स्थिति में उपयोगी हो सकता है और यहां तक ​​कि) है कि क्या करना चाहते हैं।

Btw: निम्नलिखित काम नहीं करता:

int x++; 
+0

पढ़ने के लिए मेरा मानना ​​है कि एक्स जीसीसी से 0 के लिए शुरू हो रही है, लेकिन आप के रूप में मानक के लिए पूछता है कि नहीं करता है इस व्यवहार पर भरोसा नहीं कर सकते कर सकते हैं। यह कुछ सिस्टमों पर कचरा हो सकता है। – vidit

+0

@EdHeal: नहीं, मैंने चेतावनी को सक्षम नहीं किया था और नहीं --ansi, लेकिन दोनों स्थिति को नहीं बदलते हैं (कोई चेतावनी जारी नहीं है) –

+1

एक संबंधित, कानूनी (लेकिन असामान्य) उपयोग है: 'नोड सरलग्राफ = नोड (और सरलग्राफ) ; 'एक नोड के साथ एक ग्राफ बनाने के लिए चक्रीय रूप से जुड़े हुए हैं। या यहां तक ​​कि वीरडर, 'int x = sizeof (x); '। – MSalters

उत्तर

16
अभिव्यक्ति के साथ

:

int x = x + 1; 

चर x= संकेत है, जिसके कारण आप दाहिने हाथ की ओर उपयोग कर सकते हैं पर अस्तित्व में आता है। "अस्तित्व में आता है" से, मेरा मतलब है कि चर मौजूद है लेकिन अभी तक प्रारंभिक भाग द्वारा एक मान असाइन नहीं किया गया है।

हालांकि, जब तक कि आप स्थिर भंडारण अवधि (उदा।, फ़ंक्शन के बाहर) के साथ एक चर प्रारंभ नहीं कर रहे हैं, तब तक यह अनिर्धारित व्यवहार है क्योंकि x अस्तित्व में आता है जो मनमाना मूल्य है।

सी ++ 03 इस में क्या कहना है:

एक नाम के लिए घोषणा की बात अपनी पूर्ण declarator (खंड 8) के बाद और उसके प्रारंभकर्ता (यदि हो तो) से ठीक पहले है ...

उदाहरण:
int x = 12;
{ int x = x; }
यहाँ दूसरा एक्स अपने स्वयं के (अनिश्चित) मूल्य के साथ आरंभ नहीं हो जाता।

उस दूसरे मामले में आपके प्रश्न में आपके पास बहुत कुछ है।

+0

"अस्तित्व में आता है" थोड़ा अस्पष्ट लगता है।मुझे लगता है कि यह पहले से ही '=' से पहले घोषित किया गया है, अन्यथा संकलक अज्ञात पहचानकर्ता का उपयोग करने के बारे में शिकायत करेगा। लेकिन प्रारंभिकता निश्चित रूप से '=' पर खुश होती है। – hirschhornsalz

+0

@drhirsch, मुझे नहीं लगता कि यह अस्पष्ट है, मैंने मानक में थोड़ा जोड़ा है जो यह बताता है। – paxdiablo

+0

मेरी टिप्पणी में मेरी दूसरी वाक्य बकवास है (या बहुत बुरा वाक्यांश)। मैं "अस्तित्व में आता है" वाक्यांश का जिक्र कर रहा था, जिसे आप "घोषणा का बिंदु" के रूप में उपयोग करते हैं। इसे "प्रारंभिक बिंदु" के रूप में समझा जा सकता है, जो गलत होगा। – hirschhornsalz

8

यह नहीं है, यह अपरिभाषित व्यवहार है।

आप एक गैर-आरंभिकृत चर का उपयोग कर रहे हैं - x। आपको शुद्ध भाग्य से 1 मिलते हैं, कुछ भी हो सकता है।

चेतावनी 1 चेतावनी C4700:

FYI करें, MSVS में मैं यह चेतावनी मिलती अप्रारंभीकृत स्थानीय चर 'मैं'

इस्तेमाल किया

इसके अलावा, रन-टाइम में, मैं एक अपवाद हो, तो यह निश्चित रूप से सुरक्षित नहीं है।

3

पहले मामले में तो आप बस मूल्य पहले से ही जगह पर स्मृति में उपयोग जहां चर रहा है। आपके मामले में यह शून्य लगता है, लेकिन यह कुछ भी हो सकता है। इस तरह के निर्माण का उपयोग आपदा के लिए एक नुस्खा है और भविष्य में बग खोजने में मुश्किल है।

दूसरे मामले के लिए, यह बस एक सिंटैक्स त्रुटि है। आप इस तरह एक परिवर्तनीय घोषणा के साथ एक अभिव्यक्ति मिश्रण नहीं कर सकते हैं।

5
int x = x + 1; 

मूल रूप से

int x; 
x = x + 1; 

तुम बस x में 0 के लिए भाग्यशाली रहे हैं है।

int x++; 

हालांकि सी ++ में एक पार्सर स्तर पर संभव नहीं है! पिछला पार्स किया जा सकता था लेकिन semantically गलत था। दूसरे को भी पार्स नहीं किया जा सकता है।

-1

इस अपरिभाषित व्यवहार और संकलक चाहिए कम से कम एक चेतावनी जारी करने के लिए है। g++ -ansi ... का उपयोग करके संकलित करने का प्रयास करें। दूसरा उदाहरण सिर्फ एक वाक्यविन्यास त्रुटि है।

+0

-ansi स्थिति में बदलाव नहीं करता :) –

3

चर को "=" से परिभाषित किया गया है, इसलिए यह मान्य है और जब इसे विश्व स्तर पर परिभाषित किया जाता है, तो इसे शून्य के रूप में प्रारंभ किया जाता है, इसलिए उस स्थिति में यह परिभाषित व्यवहार होता है, अन्य में चर वैसा ही अनियमित होता है अभी भी प्रारंभिक है (लेकिन 1 के साथ वृद्धि हुई)।
टिप्पणी करें कि यह अभी भी बहुत ही सस्ता या उपयोगी कोड नहीं है।

0

3.3.1 घोषणा 1 एक नाम के लिए घोषणा के बिंदु के प्वाइंट के रूप में नीचे उल्लिखित को छोड़कर, अपनी पूर्ण declarator (खंड 8) के बाद और उसके प्रारंभकर्ता से पहले (यदि हो तो) तुरंत है। [उदाहरण: int x = 12; { int x = x; } यहां दूसरा एक्स अपने (अनिश्चित) मान के साथ प्रारंभ किया गया है। अंत उदाहरण]

ऊपर राज्यों तो और अनिश्चित मान होना चाहिए, आप के साथ 1.

1

आपका कोड भाग्यशाली हैं दो possiblities है:, तो x एक स्थानीय चर रहा है

  1. आप अपरिभाषित व्यवहार है, क्योंकि आप अपने जीवनकाल से पहले किसी वस्तु के मूल्य का उपयोग करते हैं।
  2. यदि x में स्थैतिक या धागा-स्थानीय जीवनकाल है, तो यह शून्य से पूर्व-प्रारंभिक है, और आपका स्थिर प्रारंभिक रूप से इसे 1 पर विश्वसनीय रूप से सेट करेगा। यह अच्छी तरह से परिभाषित है।

तुम भी my answer that covers related cases, including variables of other types, and variables which are written to before their initialization is completed

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