2013-04-19 11 views
21

क्या noexcept फ़ंक्शन विनिर्देशक है जो संभावित रूप से जेनरेट ऑब्जेक्ट में अपवादों के लिए कोई पुस्तक-पालन कोड नहीं है, और इसलिए जब भी संभव हो, फ़ंक्शन घोषणाओं और परिभाषाओं में जोड़ा जाना चाहिए? मैं पहली जगह कॉल करने योग्य वस्तुओं के लिए रैपर के बारे में सोचता हूं, जहां noexcept कुछ अंतर कर सकता है, हालांकि जांच अभिव्यक्ति स्रोत कोड को "bloat" कर सकती है। क्या यह इसके योग्य है?क्या प्रदर्शन में सुधार करने में कोई कमी नहीं है?

+2

मुझे लगता है कि एक संकलक कि कर सकता है, लेकिन मुझे लगता है कि बिंदु टेम्पलेट्स अलग तरीके से व्यवहार करने के लिए जब वे एक अपवाद नहीं फेंक सकते हैं अनुमति देने के लिए है (वहाँ एक 'noexcept' ऑपरेटर कि' FALSE' जब रिटर्न है तर्क अभिव्यक्ति एक अपवाद वापस कर सकती है- यदि आपके पास ऐसा फ़ंक्शन है जो कभी फेंक नहीं देगा लेकिन इसे 'अस्वीकरण' के साथ टैग नहीं किया गया है तो यह सही नहीं होता है)। – Cubic

+0

यदि कोई फ़ंक्शन जिसे 'अस्वीकरण' के रूप में घोषित किया गया है, तो प्रोग्राम को समाप्त करना होगा। संकलक को समस्या को पकड़ने और कार्यक्रम को समाप्त करने के लिए कम से कम कुछ अपवाद हैंडलिंग कोड इंजेक्ट करने की आवश्यकता है। –

+0

@ डेविडरोड्रिगुएज़-ड्राईबीस: वह कोड लाइन से बाहर हो सकता है, हालांकि (सी ++ रनटाइम का हिस्सा भी)। सिद्धांत रूप में अपवाद-हैंडलिंग तंत्र ढेर को चला सकता है और प्रत्येक कॉल फ्रेम के लिए, जांच कर सकता है कि उसका कोड "अस्वीकरण" ध्वज से टैग किया गया है या नहीं। शायद इनलाइन कॉलों से निपटने के लिए अतिरिक्त जटिलता के साथ जिनके पास अपना स्वयं का फ्रेम नहीं है। चाहे कंपलर वास्तव में 'अस्वीकरण' के लिए क्या करते हैं, मैं इतना निश्चित नहीं हूं, लेकिन अक्सर यह अपवाद हैंडलर की तलाश करता है और स्टैक अनचाहे के दौरान काम करने के लिए भी किया जाता है। –

उत्तर

8

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

शायद कुछ मामलों में जहां एक nothrow विनिर्देश कुछ विशिष्ट अनुकूलन की अनुमति नहीं हैं:

int main() { 
    int i = 0; 
    try { 
     ++i; 
     thing_that_cannot_throw(); 
     ++i; 
     thing_that_can_throw(); 
     ++i; 
    } catch (...) {} 
    std::cout << i << "\n"; 
} 

यहाँ दूसरा ++ मैं सिद्धांत में कॉल करने से पहले thing_that_cannot_throw (और i सिर्फ 2 के लिए शुरू) के लिए किया जा सकता है पुनर्क्रमित । चाहे यह अभ्यास में है, एक और मामला है, हालांकि, एक कार्यान्वयन के बाद जो डीबगर में चर के राज्य के बारे में गारंटी देता है या फ़ंक्शन कॉल के ऊपर स्टैक में, i को उस कॉल के दौरान 1 मानना ​​होगा, भले ही यह एक स्थानीय चर हो किसी भी मानक का अर्थ नहीं है।

मुझे संदेह है कि संकलक की तुलना में प्रोग्रामर के लिए नोट्रो गारंटी अधिक मूल्यवान नहीं है। यदि आप कोड लिख रहे हैं जो मजबूत अपवाद गारंटी प्रदान करता है तो आमतौर पर आपके द्वारा किए जाने वाले कुछ महत्वपूर्ण संचालन होंगे, आपको नोट्रो गारंटी (स्वैप, चाल और विनाशक आम उम्मीदवार होने) की पेशकश करने की आवश्यकता है।

+0

और निश्चित रूप से, हमारे पास कंप्रेसर * चेतावनी * हो सकता है कि संभवतः 'नोएक्ससेप्ट' फ़ंक्शंस के भीतर से बाहर निकलने वाले अपवादों के बारे में हमें लाइन चलने में मदद मिल सके ... हालांकि दुर्भाग्यवश सी ++ के साथ 'नया' का व्यापक मुद्दा फेंकने में सक्षम है: ( –

+0

@MatthieuM। नया का एक नया संस्करण है, है ना? – Martin

+1

@ मार्टिन: वहाँ है, 'std :: string' का उपयोग क्या होता है? समस्या यह है कि आप एक नई 'std :: स्ट्रिंग नहीं बना सकते 'nexcept' विधि में, क्योंकि आपका कोड त्रुटिपूर्ण नहीं है, लेकिन क्योंकि आपके द्वारा चलाए जाने वाले हार्डवेयर अधिक सीमित हो सकते हैं। यह बहुत परेशान है। –

11

सैद्धांतिक रूप से बोलते हुए, noexcept प्रदर्शन में सुधार करेगा। लेकिन यह दूसरी ओर कुछ समस्याएं भी पैदा कर सकता है।

ज्यादातर मामलों में, इसे निर्दिष्ट नहीं किया जाना चाहिए क्योंकि पेशेवरों को बहुत कम माना जा सकता है और यह आपके कोड को दर्दनाक अपग्रेड कर सकता है। This post, एंड्रज द्वारा लिखित, विस्तार से कारण बताता है।

तो यह बहुत लंबा है, बस इन सुझावों मैं इसे से निष्कर्ष निकाल ले:

साथ noexcept अगर
  • वे throw() पहले से ही के साथ एनोटेट गया
    1. एन्नोटेट काम करता है,
    2. या वे अच्छे उम्मीदवार हैं (सूचीबद्ध पोस्ट में) और निश्चित रूप से फेंकने के लिए,
    3. या वे चालक-रचनाकार हैं, चाल-असाइनमेंट जिनके noexcept एनोटेशन को संकलक द्वारा सही तरीके से नहीं लिया जा सकता है और उनके उदाहरण supp हैं कुछ एसटीएल कंटेनर में रखा जाना चाहिए।
  • साथ noexcept अगर
    • आप कम प्रदर्शन के बारे में वास्तव में चिंतित हैं कार्यों पर टिप्पणी न करें,
    • या std::terminate बुला के जोखिम के बारे में,
    • या तुम सिर्फ नई सुविधा के बारे में सुनिश्चित नहीं हैं, ,
    • या आपको संदेह है कि आपको अपना कार्य noexcept बनाना चाहिए या नहीं।
  • संबंधित मुद्दे