2012-01-08 19 views
5

क्यों जीसीसी 4.7 शिकायत करता है जब एक समारोह के अंदर एक वर्ग (एक सूचक के साथ) तत्काल?जीसीसी चेतावनी [Wuninitialized]

बुरा:

#include "foo.h" 

int fn() { 
    Foo *foo; 
    foo->method(); 

    return 0; 
} 

main.cpp: सदस्य समारोह में 'int foo()': main.cpp: 21: 52: चेतावनी: 'fn' इस में अप्रारंभीकृत इस्तेमाल किया जा सकता समारोह [-Wuninitialized]

अच्छा:

#include "foo.h" 

Foo *foo; 

int fn() { 
    foo->method(); 

    return 0; 
} 

अच्छा है:

#include "foo.h" 

int fn() { 
    Foo foo; 
    foo.method(); 

    return 0; 
} 
+1

स्टेटिक चर मूल्य-प्रारंभिक हैं, इसलिए दूसरा स्निपेट चेतावनी नहीं देता है। बाकी के लिए, सी ++ के बारे में एक अच्छी किताब उठाओ। –

+0

क्या आप कृपया त्रुटियों को पोस्ट करने के लिए सावधानी बरत सकते हैं क्योंकि आपके द्वारा पोस्ट किए गए सटीक कोड के लिए कंपाइलर द्वारा रिपोर्ट की गई है। "main.cpp: सदस्य फ़ंक्शन 'int foo()' में: main.cpp: 21: 52: चेतावनी: 'fn' का उपयोग इस फ़ंक्शन में अनियमित किया जा सकता है [-नुनिनिश्लाइज्ड]" यह कोई समझ नहीं आता है, 'foo' नहीं है एक समारोह अकेले एक सदस्य समारोह दें और 'एफएन' एक चर नहीं है। –

+0

ऐसा लगता है कि आपके द्वारा प्रतिलिपि किए गए त्रुटि संदेश में नाम 'foo' और' fn' को उलट दिया गया है। या तो उस या सी ++ कंपाइलर संदेशों ने गलत स्तर का गलत स्तर प्राप्त किया है। – user268396

उत्तर

6

वहाँ Foo * foo; और Foo foo; पहले के बीच एक अंतर है एक फू करने के लिए एक सूचक वाणी, दूसरा वाणी & invokes एक फू के डिफ़ॉल्ट-निर्माता।

संपादित करें: शायद आप Foo * foo= new Foo(); लिखने के लिए, क्रम में ढेर जो समारोह कॉल से अधिक जीवित कर सकते हैं पर एक Foo आवंटित करने के लिए में था।

2

Foo* foo; foo->method()कभी नहीं अच्छा है। foo एक अनियंत्रित सूचक है जो संभावित रूप से कचरे को इंगित करता है और जैसे आपका कोड अपरिभाषित व्यवहार प्रदर्शित करता है। सर्वोत्तम आप उम्मीद कर सकते हैं कि संकलक आपको चेतावनी देता है या त्रुटिपूर्ण करता है। यदि ऐसा नहीं है, तो कम से कम उम्मीद है कि चल रहे प्रोग्राम क्रैश क्रैश।

2

आपके बुरे उदाहरण में foo पॉइंटर प्रकार के साथ एक स्थानीय चर है, जो स्वचालित रूप से प्रारंभ नहीं होता है। class Foo, आपके सही उदाहरण में, डिफ़ॉल्ट कन्स्ट्रक्टर का उपयोग करके प्रारंभ किया गया है।

आपका पहला »अच्छा« उदाहरण 0 के साथ सूचक को प्रारंभ करता है, क्योंकि foo एक वैश्विक चर है। इसके परिणामस्वरूप रनटाइम पर अपरिभाषित व्यवहार होगा, क्योंकि foo किसी ऑब्जेक्ट को इंगित नहीं करता है।

2

क्योंकि, जैसा कि चेतावनी कहता है, यह अनियमित है। अभी तक कोई वस्तु नहीं है। वास्तव में आपके पहले उदाहरण में foo का मान अपरिभाषित है। इसमें वह मूल्य होगा जो स्मृति में रहता है जहां foo रहता है।

स्पष्टीकरण के लिए, foo (जिसे आप फू * के रूप में देखते हैं) वास्तव में एक int है। int का मान फू प्रकार के ऑब्जेक्ट का पता होना चाहिए। इसे बनाने के लिए, आपको इसे foo का पता असाइन करना होगा। ऐसा करने का एक नया के साथ यह दृष्टांत के लिए है:

Foo* foo = new Foo; 

new पता जहां नई फू वस्तु बनाया गया था देता है। यह आपकी चेतावनी को हटा देगा :)

5

पहला (खराब) एक, foo एक कचरा सूचक को इंगित कर रहा है। आप इसे Foo* foo = NULL; जैसे प्रारंभ करके चेतावनी को हटा सकते हैं, लेकिन फिर जब आप इसे कम करने की कोशिश करते हैं तो आपको एक त्रुटि मिल जाएगी (रनटाइम त्रुटि)।

दूसरा (अच्छा) कोई शिकायत नहीं करता है क्योंकि सी स्वचालित रूप से अनुवाद इकाई के दायरे में शून्य या 0 या उचित समतुल्य में वैरिएबल प्रारंभ करता है यदि वे पहले से प्रारंभ नहीं किए गए हैं।

अंतिम (अच्छा) कोई शिकायत नहीं करता है क्योंकि आप ऑब्जेक्ट पर एक विधि कॉल कर रहे हैं और फ़ंक्शन पॉइंटर का असाइनमेंट कंपाइलर द्वारा किया जाता है, समान नहीं, लेकिन संख्या 2 के समान नहीं है। इसलिए संकलक पहले से ही जानता है विधि method का पता और उस पते को Foo संरचना पर उचित स्थान पर असाइन किया गया है।

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