2012-05-21 8 views
11

का कारण बनता है, इसलिए, मुझे बस एक बड़े सर्वर एप्लिकेशन के एक शानदार बहु-घंटे डीबग सत्र के साथ मिल गया। त्रुटि अंततः एक निर्माता में एक मुश्किल ध्यान देने योग्य टाइपो के लिए नीचे आ गया। असल में, यह कुछ ऐसा था:मेरी प्रारंभिक सूची में छोटे टाइपो अनपेक्षित दर्द

template <class T> 
class request_handler 
{ 
    public: 

    request_handler(T& request, Log& error_log) 
     : m_request(m_request), m_error_log(error_log) 
    { 
     /*... some code ... */ 
    } 

    ... 
}; 

बग देखें? अच्छा, मैंने नहीं किया। समस्या प्रारंभकर्ता सूची में एक छोटा टाइपो है: m_request(m_request) अपने लिए एक अनिवार्य संदर्भ असाइन कर रहा है। जाहिर है, इसे m_request(request) पढ़ना है।

अब, सदस्य चर m_requestT& प्रकार का है। तो - क्या कुछ कारण है कि संकलक ने मुझे चेतावनी नहीं दी है कि मैं यहां एक अनियमित चर का उपयोग कर रहा था?

-Wall ध्वज के साथ जीसीसी 4.6 का उपयोग करना, अगर मैं कहूँ:

int x; 
x = x; 

... यह एक चेतावनी जारी करेगा: warning: ‘x’ is used uninitialized in this function [-Wuninitialized]

तो, क्यों संकलक नहीं था मुझे चेतावनी जब मैं सौंपा m_request खुद के लिए: अनिवार्य रूप से एक अनियमित संदर्भ असाइन करना? यह मुझे परेशानियों के घंटे बचा लिया होगा।

+0

क्या आपने इसे पूर्ण अनुकूलन सक्षम (-O3) के साथ संकलित किया था? कंपाइलर केवल इन गलतियों में से कुछ को नोटिस करेगा जब यह वास्तव में डेटा-प्रवाह विश्लेषण करता है। बस एम_ उपसर्ग को छोड़ने पर विचार करें। 'foo (टी बार): बार (बार) 'पूरी तरह से अच्छी तरह से परिभाषित है। – xDD

+0

पहले मैं अनुकूलन के साथ संकलित था। लेकिन डिबगिंग करते समय, मैं '-g3' ध्वज के साथ संकलित था इसलिए मैं डीबगर का उपयोग कर सकता था। यहां तक ​​कि 'g3' ध्वज के साथ भी यह कोई चेतावनी जारी नहीं किया। – Channel72

+0

मैं इस चेतावनी का कारण बनने के लिए '-g3' की अपेक्षा नहीं करता हूं, यह सब आपके प्रतीक को डंप कर देता है। – xDD

उत्तर

11

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

class C { 
     int a, b; 
public: 
     C(int t, int z) : a(a), b(z) { }; 
}; 

बजना -Wuninitialized के साथ इस पर चेतावनी देते हैं।

जीसीसी लोगों के लिए अच्छी खबर: gnu के बगजिला, gcc 4.7.0 has fixed this के अनुसार।

अद्यतन

जीसीसी 4.7.0 पर, -Wself-init जोड़ने इस चेतावनी (sbellef द्वारा सत्यापित) प्राप्त करने के लिए:

tst.cc: निर्माता 'में सी :: सी (int, int) ': tst.cc:4:9: चेतावनी:' सी :: के साथ ही प्रारंभ एक 'है [-Wuninitialized]

+0

उत्सुकता से, मुझे सदस्य संदर्भों का उल्लेख करते हुए बग दस्तावेज़ नहीं दिखाई देता है, लेकिन शायद फिक्स दोनों मामलों को समान करता है। –

+1

अच्छा बिंदु। 4.7.0 वाला कोई भी व्यक्ति इसे घुमा देना चाहता है? –

+0

मेरे सिस्टम 'जीसीसी संस्करण 4.7.0 20120505 (प्रीरलीज) (जीसीसी) पर जीसीसी त्रुटि की रिपोर्ट नहीं करता है। दूसरी तरफ, क्लैंग इसे सही तरीके से रिपोर्ट करता है: 'clang ++ -Wall -c tst.cc tst.ccvertis:29: चेतावनी: यहां उपयोग किए जाने पर फ़ील्ड को प्रारंभिक नहीं किया गया है [-Wuninitialized] सी (int t, int z): ए (ए), बी (जेड) {}; ^ 1 चेतावनी उत्पन्न हुई। – sbellef

3

मैं निर्माता के रूप में सदस्यों के लिए एक ही नाम का उपयोग करने का चाल का उपयोग करना चाहते पैरामीटर रों।

template <class T> 
request_handler(T& request, Log& error_log) 
: request(request), error_log(error_log) 
{ 
    /*... some code ... */ 
} 

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

+0

यही कारण है कि यह 'टी कॉन्स्ट और अनुरोध 'होना चाहिए - आपको केवल' यह-> अनुरोध 'शुरू करने के लिए तर्क की आवश्यकता है, आप इसे संशोधित नहीं करेंगे। यदि आपका उपयोग केस अधिक जटिल है, तो मैं इसके खिलाफ अनुशंसा करता हूं। लेकिन यदि आप सरल मामले में लगातार इस पैटर्न का उपयोग कर रहे हैं, तो अतिरिक्त लाभ यह है कि पैटर्न पहचानने योग्य हो जाता है। "ओह, वह पैरामीटर 'फू' सिर्फ 'फू' शुरू करने के लिए है। मैं 'बार' में देख रहा हूं इसलिए मुझे 'फू' के बारे में परवाह करने की आवश्यकता नहीं है। – MSalters

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