2012-05-16 6 views
5

निम्नलिखित की तरह देखते हुए कोड:सी ++ में int के लिए एक शाब्दिक असाइनमेंट अपवाद फेंक सकता है?

void f() 
{ 
    int i; 
    i = 0; 
} 

यह संभव है प्रणाली सरल काम की वजह से एक अपवाद फेंक सकता है?

[संपादित करें: उन लोगों के लिए, "कोई अपवाद नहीं हो सकता है," क्या आप मुझे सी ++ मानक के हिस्से की दिशा में इंगित कर सकते हैं जो यह कहता है? मुझे इसे खोजने में परेशानी हो रही है।]

+6

हमेशा प्रकार 'int' और आरएचएस हमेशा एक शाब्दिक प्रकार है? या आप सामान्य मामले के बारे में पूछ रहे हैं? (जो भी आपने दिखाया वह असाइनमेंट नहीं था) – Flexo

+0

उस बिंदु को पकड़ने के लिए धन्यवाद। मैंने उदाहरण संपादित किया। वास्तव में, दोनों के लिए, आपके पहले प्रश्न के लिए। –

उत्तर

7

हालांकि आप मानक में इसका आश्वासन पाने के लिए शायद कड़ी मेहनत कर सकते हैं, अंगूठे का एक साधारण नियम यह है कि सी में वैध कुछ भी संभवतः फेंक नहीं सकता है। [संपादित करें: सबसे करीब मैं इस आशय का एक सीधा बयान के बारे में पता कर रहा हूँ §15 की/2 पर है, जो कहता है कि:

कोड निष्पादित करता है कि एक फेंक अभिव्यक्ति "एक अपवाद फेंकने के लिए कहा जाता है , "[...]

कि रिवर्स में को देखते हुए, कोड है कि एक थ्रो-अभिव्यक्ति निष्पादित नहीं करता है एक अपवाद फेंक नहीं है]

फेंक मूल रूप से दो संभावनाओं के लिए प्रतिबंधित है। पहला है यूबी का आह्वान दूसरा सी ++ के लिए अद्वितीय कुछ कर रहा है, जैसे कि उपयोगकर्ता द्वारा परिभाषित प्रकार को असाइन करना जो operator = ओवरलोड करता है, या new अभिव्यक्ति का उपयोग करता है।

संपादित करें: जहां तक ​​एक असाइनमेंट जाता है, वहां फेंकने के कुछ तरीके हैं। जाहिर है, असाइनमेंट ऑपरेटर में फेंकना ही ऐसा करेगा, लेकिन दूसरों की एक उचित संख्या है। उदाहरण के लिए, यदि स्रोत प्रकार लक्ष्य प्रकार से मेल नहीं खाता है, तो आप स्रोत में एक कास्ट ऑपरेटर या लक्ष्य में एक कन्स्ट्रक्टर के माध्यम से रूपांतरण प्राप्त कर सकते हैं - जिनमें से कोई भी फेंक सकता है।

+0

संसाधनों पर सीमा लागू करने के लिए कार्यान्वयन मुक्त नहीं हैं? यदि वे "अब और ढेर नहीं हैं और कोई रजिस्ट्रार नहीं हैं" (कम से कम सैद्धांतिक रूप से) फेंकने का एक वैध कारण होगा और केवल पहले उपयोग पर देखा जाएगा? – Flexo

+0

सिद्धांत में हां। वीसी ++ 6 (एक उदाहरण के लिए) ने इस तरह की चीजें की - लेकिन यह काफी खराब काम करता है कि वीसी ++ अब और नहीं है, और मैं कम से कम आश्चर्यचकित हूं कि किसी और को जल्द ही इसे आजमाएं। –

+0

@ जेरीकॉफिन "वैध में सी" की पर्याप्त सख्त परिभाषा के लिए। एक int को एक फ़्लोटिंग पॉइंट को असाइन करने के परिणामस्वरूप अपरिभाषित व्यवहार हो सकता है, और अपवाद केवल अपरिभाषित व्यवहार के मामले में कुछ भी मान्य है (हालांकि शायद कार्यान्वयन बिंदु की गुणवत्ता से नहीं)। –

0

यदि यह सिर्फ int है, तो नहीं - यह फेंक नहीं देगा।

यदि यह कुछ अधिक जटिल है, जैसे कि वेक्टर, तो यह कई कारणों से फेंक सकता है (उदाहरण के लिए आवंटन विफलता या द्वितीयक थ्रेड से परिवर्तन)।

+0

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

2

यह केवल एक मामले में अपवाद फेंक सकता है: जब उन दो प्रकारों के लिए operator=() ओवरलोड किया गया; समान, जब रूपांतरण की आवश्यकता होती है, कनवर्टिंग कन्स्ट्रक्टर या operator T() भी फेंक सकता है। यह तब सटीक कार्यान्वयन पर निर्भर करता है - यह पता लगाने के लिए कि क्या यह फेंक देगा, आप जिस लाइब्रेरी का उपयोग कर रहे हैं उसके दस्तावेज़ीकरण में इसके बारे में जानकारी देखें।

6

काफी चीजें हैं जो कि एक तरह से या किसी अन्य फेंक सकता कार्य की तरह लग रही का एक बहुत है:

int operator"" _t(const char *) { throw 0; } // C++11 user defined literal 

struct foo { 
    foo(int) { throw 0; } 
    operator int() { throw 0; } 
    foo& operator=(int) { throw 0; } 
}; 

int main() { 
    int i; 
    i = 0; // can't throw 
    i = 0_t; // User defined literal throws 
    foo f = 0; // Constructor throws 
    i = f; // conversion operator throws 
    f = 0; // assignment throws 
    f = f; // both conversion and assignment would like to throw 
} 

(से सी ++ 11 नया एक सहित)

3

आप के बारे में चिंतित हैं, तो 0 (जिसमें int टाइप किया गया है) int, मानक के §5.17 मानक असाइनमेंट ऑपरेशन के बहुत से अर्थशास्त्र निर्दिष्ट करता है, और कोई अपवाद नहीं हो सकता है। यदि आप int, §5.17 पर मनमाने ढंग से अभिव्यक्ति निर्दिष्ट करने के बारे में चिंतित हैं, तो “ अभिव्यक्ति को स्पष्ट रूप से बाएं ऑपरेंड के सीवी-अयोग्य प्रकार में परिवर्तित कर दिया गया है।"सही संकार्य के वास्तविक प्रकार पर निर्भर करता है:

  • यदि यह एक अभिन्न प्रकार है, यदि वास्तविक मूल्य एक int में नहीं दर्शाया जा सकता है, परिणाम परिभाषित कार्यान्वयन कर रहे हैं (सी मानक अधिक स्पष्ट है: यदि शून्य करने के लिए काट-छांट के बाद मूल्य नहीं दर्शाया जा सकता है कि यह या तो एक कार्यान्वयन परिभाषित मूल्य के साथ एक int में परिणाम चाहिए, या अगर यह एक चल बिन्दु मूल्य है आप एक कार्यान्वयन परिभाषित संकेत मिल जाएगा)

  • , परिणाम अपरिभाषित व्यवहार है int में, व्यवहार अपरिभाषित है (इसलिए आपको अपवाद मिल सकता है)

  • यदि यह उपयोगकर्ता परिभाषित प्रकार है, तो उपयोगकर्ता परिभाषित रूपांतरण ऑपरेटर को बुलाया जाएगा। जो अपवाद फेंक सकता है।

आप अन्य प्रकार बताए बारे में चिंतित हैं: गैर वर्ग प्रकार के प्रत्येक सेट के लिए, वहाँ ऊपर की तरह नियमों की एक सूची है, लेकिन केवल संभव अपवाद एक परिणाम के रूप में हो जाएगा रूपांतरण टाइप करें। कक्षा प्रकारों के लिए, operator= का उपयोग किया जाएगा। जो अपवाद फेंक सकता है, इसमें क्या है इसके आधार पर।