2010-07-13 4 views
21
#include <stdio.h> 
int main() { 
    int c = c; 
    printf("c is %i\n", c); 
    return 0; 
} 

मैं c नामक एक पूर्णांक चर परिभाषित कर रहा हूं, और मैं अपने मूल्य को स्वयं ही निर्दिष्ट कर रहा हूं। लेकिन यह कैसे संकलित कर सकते हैं? c प्रारंभ नहीं किया गया है, तो इसका मूल्य स्वयं को कैसे सौंपा जा सकता है? जब मैं प्रोग्राम चलाता हूं, तो मुझे c is 0 मिलता है।यह सी कोड संकलित क्यों करता है?

मुझे लगता है कि संकलक असेंबली कोड उत्पन्न कर रहा है जो c चर के लिए स्थान आवंटित कर रहा है (जब संकलक int c कथन का सामना करता है)। फिर यह अन-प्रारंभिक स्थान में जो भी जंक वैल्यू लेता है और इसे c पर वापस सौंपता है। क्या यह हो रहा है?

+3

दुर्भाग्यवश, इसकी अनुमति है - आप आम तौर पर संकलक को इसके बारे में एक चेतावनी उत्सर्जित कर सकते हैं, उदाहरण के लिए -Wall ध्वज का उपयोग करके g ++ (लेकिन किसी कारण से जीसीसी नहीं) का उपयोग करके चेतावनी उत्पन्न होती है। –

+7

@Neil, जीसीसी के साथ एक त्रुटि को मजबूर करने के लिए, आप '-Werror = uninitialized -Winit-self' –

उत्तर

30

मुझे पिछले जवाब में यह उद्धृत करना याद है लेकिन मुझे इस समय यह नहीं मिल रहा है।

सी ++ 03 §3.3.1/1:

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

इसलिए परिवर्तनीय सी प्रारंभिक भाग से पहले उपयोग करने योग्य है।

संपादित करें: क्षमा करें, आप सी के बारे में पूछा विशेष रूप से; हालांकि मुझे यकीन है कि वहां एक समतुल्य रेखा है।

C99 §6.2.1/7:: जेम्स McNellis यह पाया "। कि सिर्फ अपनी declarator के पूरा होने के बाद शुरू होता है गुंजाइश है" कोई भी पहचानकर्ता है कि एक संरचना, संघ, या गणन टैग नहीं है घोषणाकर्ता के बाद प्रारंभकर्ता है।

+0

स्पॉट पर! '+ 1' ....... –

+0

धन्यवाद! उत्कृष्ट स्पष्टीकरण! –

+12

सी 99 §6.2.1/7: कोई भी पहचानकर्ता जो संरचना, संघ या गणना टैग नहीं है "का दायरा है जो इसके घोषणाकर्ता के पूरा होने के ठीक बाद शुरू होता है।" घोषणाकर्ता के बाद प्रारंभकर्ता है। –

2

सी शुरू किया गया है!

हालांकि यह कोड की एक पंक्ति है, लेकिन वास्तव में यह पहले सी शुरू करना है, फिर इसे सी असाइन करना। आप बस भाग्यशाली हैं कि संकलक आपके लिए शून्य से शून्य शुरू कर रहा है।

+0

-1 का उपयोग करते हैं ...गुमराह और गलत, लेकिन अभी भी उच्चतम वोट दिया गया है ... दिखाए गए उदाहरण में चर 'c' एक सूचक नहीं है, लेकिन ढेर पर आवंटित किया गया है। – gnud

+4

क्या? किसने कहा कि यह एक सूचक होना था? –

+1

असहमत - 'c' मेरे लिए अनियमित है (कंपाइलर विकल्पों के आधार पर), इस कोड को चलाने के दौरान भिन्न, गैर-शून्य आउटपुट द्वारा प्रमाणित। – pilcrow

5

यह अपरिभाषित व्यवहार एक गैर-आरंभिकृत मूल्य का उपयोग करने के (§C99 J.2 "स्वचालित भंडारण अवधि के साथ एक वस्तु का मूल्य प्रयोग किया जाता है, जबकि यह अनिश्चित है")। तो nasal demons से सी = 0, playing Nethack से कुछ भी हो सकता है।

+0

मूल्य अनिश्चित है, लेकिन यह अपरिभाषित व्यवहार नहीं है। नाक राक्षस, और नेथैक बाहर हैं। सी = 0 संभव है (और संभावना है)। यहां व्यवहार को यादृच्छिक संख्या जनरेटर के समान तरीके से परिभाषित किया गया है, हालांकि हम परिणामस्वरूप मूल्य निर्धारित नहीं कर सकते हैं, हम मानक द्वारा गारंटी दी जा सकती है कि मूल्य इस कथन के बारे में अज्ञात एकमात्र चीज है। –

11

आपका अनुमान बिल्कुल सही है। int c वैरिएबल के लिए स्टैक पर स्पेस को धक्का देता है, जिसे c = c भाग के लिए फिर से लिखा और फिर से लिखा जाता है (हालांकि संकलक इसे अनुकूलित कर सकता है)। आपका कंपाइलर 0 पर मान को दबा रहा है, लेकिन यह हमेशा मामला होने की गारंटी नहीं है।

+0

+1 अच्छी तरह से समझाया। –

+4

इसकी संभावना 0 को धक्का नहीं दे रही है, ऐसा लगता है कि मौजूदा स्टैक फ्रेम में पहले से ही 0 मेमोरी है। 0 पर निर्भर करता है कि निश्चित रूप से अनिर्धारित है। –

+0

+1 बहुत उपयोगी! –

2

सी विनिर्देश यह सुनिश्चित नहीं करता है कि चर 0, 0.0 और न ही "" या "" शुरू हो जाएंगे।

यह कंपाइलर की सुविधा है और आपको कभी भी ऐसा नहीं करना चाहिए।

मैं हमेशा इसके बारे में चेतावनी देने के लिए अपना आईडीई/कंपाइलर सेट करता हूं।