2015-10-04 6 views
6

मैं नई सी ++ भाषा सुविधाओं जैसे एम्बेडेड सिस्टम (एसआरएएम के 16 केबी और फ्लैश के 64 केबी, कॉर्टेक्स एम 4) पर इटरेटर का उपयोग कर देख रहा हूं और एक आश्चर्यजनक रोडब्लॉक मारा। पृथ्वी पर इतने बड़े पैमाने पर इटरेटर क्यों हैं? मैं इस धारणा के तहत था कि वे मूल रूप से कुछ सूचक अंकगणितीय या अनुक्रमण हैं। एसटीएल कुछ अप्रत्याशित कोड में खींच रहा है?सी ++ इटरेटर्स का उपयोग क्यों() या इंडेक्सिंग की तुलना में कोड आकार में भारी वृद्धि करता है?

ये निम्नलिखित झंडे का उपयोग करते हुए here से gcc-arm-none-eabi-4_9 टूलचेन के साथ विंडोज़ पर किनेटिस डिज़ाइन स्टूडियो का उपयोग कर रहे हैं।

arm-none-eabi-g++ -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Os -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -fsingle-precision-constant -flto -g3 -I"../Sources" -I"../Includes" -std=gnu++11 -fabi-version=0 -std=c++11 -MMD -MP -MF"Sources/System.d" -MT"Sources/System.o" -c -o "Sources/System.o" "../Sources/System.cpp" 

आईटीएम_SendChar बस एक सिंगल लेता है और इसे एक रजिस्टर में रखता है।

std::string input = "Oh hai there! :D\n"; 

#ifdef char_array 
    // .text    7352 
    // .data    376 
    // .bss    236 
    for(int i = 0; i < input.size(); i++) 
      ITM_SendChar(input[i]); 
#endif 

#ifdef char_at 
    // .text    7392 
    // .data    376 
    // .bss    236 
    for(int i = 0; i < input.size(); i++) 
     ITM_SendChar(input.at(i)); 
#endif 

#ifdef char_itterator 
    // .text    39744   
    // .data    384 
    // .bss    252 
    for(char some_char : input) 
     ITM_SendChar(some_char); 
#endif 

#ifdef char_itterator_auto 
    // .text    39744   
    // .data    384 
    // .bss    252 
    for(auto some_char : input) 
     ITM_SendChar(some_char); 
#endif 

#ifdef char_itterator_auto_no_copy 
    // .text    39744   
    // .data    384 
    // .bss    252 
    for(auto& some_char : input) 
     ITM_SendChar(some_char); 
#endif 
+2

क्या आप कुछ डीबग कॉन्फ़िगरेशन में संकलित कर रहे हैं? मैं आपके निर्माण पर्यावरण को नहीं जानता, लेकिन, उदाहरण के लिए, विजुअल सी ++ की डीबग कॉन्फ़िगरेशन में सभी प्रकार की जांच की जाती है। – JohnB

+1

सबसे पहले आपको सेब से सेब की तुलना करना चाहिए और लूप के लिए श्रेणीबद्ध प्रतियों में प्रतिलिपि बनाना नहीं चाहिए। यदि आप 'ऑटो और some_char: इनपुट' का उपयोग करते हैं तो क्या होता है? – NathanOliver

+0

सुझाव के लिए धन्यवाद @ नाथनऑलिवर, लेकिन कोई बदलाव नहीं। मैंने परिणामों को मेरे प्रश्न में जोड़ा। और जॉनबी डीबगिंग के लिए -जी 3 ध्वज है लेकिन इसे हटाने से कोई फर्क नहीं पड़ता। जहां तक ​​मुझे पता है कि केडीएस में डिबगिंग के दौरान अतिरिक्त कुछ भी शामिल नहीं है। – hak8or

उत्तर

1

एक (या दो) सी ++ मानकों पहले यह कानूनी था iterators संकेत के साथ लागू किया जाए। (आप इसके बारे में और जानने के लिए मानक में "हटाए गए वीज़ल शब्द" को Google पर जा सकते हैं।) नए मानकों को इटरेटर से अधिक की आवश्यकता होती है, उदाहरण के लिए यदि आपके पास दो प्रकार के दो कंटेनर हैं, तो उन दो कंटेनरों को स्वैप करना उन दो पुनरावृत्तियों को स्वैप करने की आवश्यकता है (यदि आप चाहें तो इसे अपने लिए पढ़ने के लिए N4527 23.2.1 फुटनोट 9 देखें)। इसका मतलब यह है कि इटरेटर्स के बजाय इंडेक्स वाले कंटेनर में अनुक्रमण करना निश्चित रूप से अधिक कुशल हो सकता है। यह सिर्फ इतना है कि सभी मानक कंटेनर प्रकारों के लिए समर्थित नहीं है ... और यही कारण है कि इटरेटर का उपयोग कोड आकार बढ़ाता है।

3

[] ऑपरेटर और .at (के बीच मुख्य अंतर) कि .at() सीमा की जाँच करता है, और अगर सूचकांक सीमा से बाहर है एक अपवाद फेंक देते हैं।

ऐसा लगता है कि आप जिस मानक लाइब्रेरी कार्यान्वयन का उपयोग कर रहे हैं वह किसी इटरेटर का उपयोग करते समय अतिरिक्त कोड में लिंक कर रहा है। कारण खोजने का एकमात्र तरीका दोनों संस्करणों के लिए लिंकर मानचित्र फ़ाइल की जांच करना है, और आपके द्वारा उपयोग किए जा रहे कार्यों के लिए स्रोत कोड पर बारीकी से देखो, और शायद जेनरेट की गई असेंबली भी हो सकती है।

सामान्य रूप से, यदि आपको अपने कोड को बहुत छोटा होने की आवश्यकता है तो आप किसी भी मानक पुस्तकालय का उपयोग करने से बचना चाहते हैं, क्योंकि वहां के कार्य उनके साथ बहुत सारे कोड और डेटा खींच सकते हैं। यहां तक ​​कि वह कोड जो कमांड लाइन को उस प्रारूप में पार करता है जो मुख्य() अपेक्षा करता है वह काफी बड़ा हो सकता है।

तुलना के लिए, इस प्रयास करें:

const char *input = "Oh hai there! :D\n"; 

while (*input) 
     ITM_SendChar(*input++); 
+0

जो आपने अभी दिखाया है वह भी कोड आकार के संदर्भ में पूरी तरह से पर्याप्त है, धन्यवाद। मैं बस एम्बेडेड के लिए इटेटर जादू पर आने की उम्मीद कर रहा था क्योंकि दोनों ऐसा लग रहा था कि यह बहुत उपयोगी हो सकता है और इसके बारे में मेरी समझ के कारण न्यूनतम कोड आकार प्रभाव पड़ता है, लेकिन दुख की बात यह है कि ऐसा नहीं है। मैं बाद में लिंकर मैप फ़ाइल में देखूंगा कि क्या यह पता चल सकता है कि क्या हो रहा है और यदि कोई कामकाज है तो मैं अब भी अपने सभी फ्लैश को डोडो के रास्ते के बिना इटरेटर का उपयोग कर सकता हूं। – hak8or

+0

@ hak8or - * "जो आपने अभी दिखाया है वह भी कोड आकार के मामले में पूरी तरह से पर्याप्त है ..." * - आप अक्सर 'CXXFLAGS + = -फंक्शन-सेक्शन -फडाटा-सेक्शन' और 'एलडीएफएलजीएस + = -ब्लूएल का उपयोग करते हैं, - कोड आकार को कम करने के लिए -gc-section'। लेकिन यह एक अलग समस्या/प्रश्न है * "सी ++ इटरेटर्स का उपयोग कोड() और इंडेक्सिंग की तुलना में कोड आकार में भारी क्यों होता है?" * और * "धरती पर इतने बड़े पैमाने पर इतने बड़े क्यों हैं?" * – jww

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

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