2013-08-16 4 views
12

(अल्पविराम अभिव्यक्ति विभाजित) जबकि हमारे कोड (C++) के कुछ डिबगिंग मैं इस पाया:reinterpret_cast विचित्रता

inline std::string BufferToStr(
    const unsigned char* buffer, 
    int index, 
    size_t length) 
{ 
    std::string retValue(reinterpret_cast<const char*>(&buffer[index], length)); 
    return retValue; 
} 

इस कोड के साथ इस मुद्दे (सूचक और स्ट्रिंग लंबाई चेकों की कमी की ओर मुख) कि बंद है reinterpret_cast के कंस्ट्रैसिस length के बाद रखा गया है जब यह &buffer[index] के बाद किया जाना चाहिए था। सबसे पहले मैंने सोचा कि यह संकलक (वीएस2013 का उपयोग करके) के साथ एक मुद्दा था लेकिन वीएस2012 और जीसीसी 4.6.3 दोनों का उपयोग करके इसे सफलतापूर्वक संकलित करने के बाद, मैं इस निष्कर्ष पर आया हूं कि यह किसी कारण से अनुमति है। कोड या तो विंडोज या लिनक्स पर नहीं चलेंगे क्योंकि लंबाई पैरामीटर पॉइंटर के रूप में उपयोग किया जाता है।

तो मेरा सवाल यह है कि यह संकलन क्यों करता है? reinterpret_cast के दस्तावेज़ीकरण को देखते हुए मुझे इस पर कोई दस्तावेज नहीं मिल रहा है कि आप इसे अल्पविराम से अलग मूल्यों की सूची पास कर सकते हैं और इसके साथ क्या करेंगे।

+0

इसे संकलित क्यों नहीं करना चाहिए? आप कंपाइलर को 'size_t' को' const char * 'पर डालने के लिए कह रहे हैं, और यह ऐसा करता है। इसे अनुमति देने की आवश्यकता नहीं है। – Damon

+0

ध्यान दें कि चेतावनी को सक्षम करने से 'जीसीसी' का उपयोग करके एक उदाहरण के साथ मेरे उत्तर में दिखाए गए अनुसार एक मजबूत संकेत दिया गया होगा। –

उत्तर

12

reinterpret_castexpression स्वीकार करता है। आपके पास कोष्ठक में क्या है एक अभिव्यक्ति - "," operator दो उप-अभिव्यक्तियों के साथ, जो अंतिम उप-अभिव्यक्ति के परिणामस्वरूप मूल्यांकन करेगी।

+0

कॉमा ऑपरेटर जवाब था। मैं उस बारे में भूल गया था। स्ट्रॉस्ट्रप के पुराने "एनोटेटेड सी ++ रेफरेंस मैनुअल" में सेक्शन 5.18 पर एक त्वरित रूप से यह काफी अच्छी तरह से समझाया गया। आपके त्वरित उत्तर के लिए धन्यवाद। – william

4

यह comma operator है। यह अल्पविराम के दोनों किनारों पर अभिव्यक्तियों का मूल्यांकन करता है, लेकिन दाएं हाथ की अभिव्यक्ति के परिणाम को वापस कर देता है।

संकलक शिकायत नहीं करता है क्योंकि आप संकलक को सरल बताते हैं कि अभिव्यक्ति का परिणाम (प्रकार size_t) का इलाज किया जाना चाहिए क्योंकि यह const char* अभिव्यक्ति थी। यही reinterpret_cast करता है, यह लगभग किसी भी प्रकार के कास्टिंग को लगभग किसी भी अन्य प्रकार तक कास्टिंग करने की इजाजत देता है, इससे कोई फर्क नहीं पड़ता कि यह कितना बेवकूफ हो सकता है।

3
reinterpret_cast <new_type> (expression)   

reinterpret_cast एक expression स्वीकार करते हैं। यहां आपके पास एक अल्पविराम ऑपरेटर है जो दोनों पक्षों के अभिव्यक्तियों का मूल्यांकन करता है और राघ-हाथ अभिव्यक्ति देता है।

वास्तव में, अभिव्यक्ति (&buffer[index], length)(length) के बराबर है।

बस देखें: http://msdn.microsoft.com/en-us/library/zs06xbxh.aspx या http://en.wikipedia.org/wiki/Comma_operator अल्पविराम ऑपरेटर स्पष्टीकरण के लिए।

निष्कर्ष के लिए, यहाँ आप एक const char* करने के लिए एक size_t (अभिव्यक्ति की परिणाम) कास्ट करने के लिए अपने संकलक कह रहे हैं और ऐसा लगता है कि कर सकते हैं।

7

यह सी/सी ++ में comma operator के कारण है। कोड (एक अभिव्यक्ति):

(&buffer[index], length) 

के बराबर है (& बफर [सूचकांक] कोई प्रभाव नहीं लेने के लिए):

inline std::string BufferToStr(const unsigned char* buffer, int index, size_t length) 
{ 
    std::string retValue(reinterpret_cast<const char*>(length)); 
    return retValue; 
} 
2
:

(length)

तो अपने कोड के बराबर है

यह एक कारण है कि चेतावनियां सक्षम करना महत्वपूर्ण क्यों है, शायद यह आपको स्वयं को हल करने में मदद करेगा।

warning: left operand of comma operator has no effect [-Wunused-value] 
std::string retValue(reinterpret_cast<const char*>(&buffer[index], length)); 
                   ^

आप live example देख सकते हैं: gcc का उपयोग करना और -Wall साथ चल रहा है, यह चेतावनी मुझे प्राप्त हुआ है।

चेतावनी है कि हम comma operator पहली बार में उपयोग कर रहे हैं हमें बताता है यह puzzling एक सा हो सकता है लेकिन reinterpret_cast एक समारोह कॉल, जिसमें इस कोष्ठक का उपयोग कर के बिना काम नहीं होता, जैसा कि हम in this contrived example देख सकते हैं नहीं है, लेकिन एक अभिव्यक्ति और अनुभाग में 5.2पोस्टफिक्स भाव मसौदा सी ++ मानक पोस्टफ़िक्स अभिव्यक्ति के लिए व्याकरण होता है की:

postfix-expression: 
    ... 
    reinterpret_cast < type-id > (expression) 
    ... 

और हम तर्क तो 0,123,366 में एक expression उपयोग कर सकते हैंपूरी तरह से मान्य है।

+1

मैं इस पर पूरी तरह से आपसे सहमत हूं और मेरे पास आमतौर पर चेतावनी स्तर होता है -Wall। इस प्रोजेक्ट में इसे विजुअल स्टूडियो में लेवल 3 पर सेट किया गया था और इससे कोई चेतावनी नहीं मिली, मैंने इसे बदल दिया -वॉल लेकिन अभी भी इस बारे में चेतावनी नहीं दी। तो यह जीसीसी की तरह लगता है, कम से कम इस मामले में, चेतावनियों की रिपोर्टिंग में बेहतर है। – william

+0

@ विल्लियम मैंने एक 'gcc' उदाहरण का उपयोग किया क्योंकि आपने उल्लेख किया था कि आपने 'gcc 4.6.3' को भी कोशिश की है और कम से कम' 4.4.4' तक' gcc' को भी चेतावनी दी गई है, 'क्लैंग' भी एक अच्छी चेतावनी देता है। –

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