2010-08-16 12 views
27

"We do not use C++ exceptions.""हम सी ++ अपवादों का उपयोग नहीं करते हैं" - विकल्प क्या है? इसे दुर्घटनाग्रस्त होने दें?

आप अपवाद का उपयोग नहीं करते हैं, तो क्या होता है जब उसमें कोई त्रुटि है? आप प्रोग्राम को दुर्घटनाग्रस्त होने दें?

+25

कृपया, दुनिया में जो कुछ भी अच्छा है, उसके लिए Google Code Style Guide को अपनाना न करें। यह आधुनिक सी ++ परियोजनाओं के लिए भयानक है। [बस इसे अनदेखा करें।] (Http://stackoverflow.com/questions/3312513/on-a-disadvantage-of-exceptions-in-c/3312577#3312577) – GManNickG

+4

एक ऐसा मामला है जहां मैं सोच सकता हूं कि अपवाद नहीं हैं एक विकल्प (एम्बेडेड सी ++ के अलावा जहां उन्हें समर्थित नहीं किया जा सकता है) - एक सार इंटरफ़ेस के माध्यम से साझा लाइब्रेरी के भीतर अपनी सी ++ कक्षा को उजागर करते समय। ऐसे मामलों में, चाहे वह आपके स्वयं के कस्टम डीएलएल (या .so), या COM इंटरफ़ेस या XPCOM इंटरफ़ेस हों, कुछ नामों के लिए, आप इंटरफ़ेस सीमा पार करने वाले अपवाद नहीं रख सकते हैं। इसलिए आपको सभी अपवादों को पकड़ने और इसके बजाय त्रुटि कोड लौटने का सहारा लेना होगा। अन्यथा मैं जीएमएन से सहमत हूं, अपवादों का उपयोग न करने की समस्या सिर्फ इसके लायक नहीं है। – Praetorian

+6

सी में अपवाद नहीं हैं, यह अभी भी आपको असाधारण मामलों से निपटने देता है। आप सी ++ में भी ऐसा कर सकते हैं। – nos

उत्तर

7

यदि आप परिभाषा के अनुसार अपवादों का उपयोग नहीं करते हैं तो कोई कोड अपवाद नहीं फेंक देगा, इसलिए पकड़े जाने की आवश्यकता नहीं होगी।

यह "हम सी ++ अपवादों का उपयोग नहीं करते हैं", नहीं "हम सी ++ अपवाद नहीं पकड़ते हैं"।

+1

आह हमारे पास त्रुटियां नहीं हैं, इसलिए हमें उन्हें संभालना नहीं है?किसी प्रोग्राम को क्रैश करने के लिए आपको अपवादों की आवश्यकता नहीं है, त्रुटि को अनदेखा करने के बाद अमान्य मेमोरी स्थानों पर लिखना ठीक होगा। इसलिए आपके प्रोग्राम क्रैश को अपवादों के विकल्पों में से एक है। – josefx

+1

@josefx: मानक सी ++ में एक अवैध स्मृति स्थान पर लिखना अपरिभाषित व्यवहार है। सी ++ मानक यह निर्धारित नहीं करता है कि इसे अपवाद फेंकना चाहिए, वास्तव में लिनक्स पर उदाहरण के लिए यह नहीं है (यह संकेत भेजता है)। असल में, मुझे नहीं लगता कि ऐसा होने पर किसी भी ओएस पर अपवाद फेंक दिया जाता है। मेरा मानना ​​है कि विंडोज वैकल्पिक रूप से एक संरचना अपवाद फेंकता है (जो सी ++ अपवाद से अलग है), लेकिन यह इसके बारे में है। –

+1

मेरा मतलब था कि एक त्रुटि को अनदेखा करने के बाद प्रोग्राम पहले से ही एक अमान्य स्थिति में है और सिग्नल सबसे अधिक संभावना है कि इसे मार डालें => आप इसे दुर्घटनाग्रस्त होने दें। अपवादों का उपयोग नहीं करने से C++ की बिल्डिन त्रुटि प्रबंधन को हटा दिया जाता है और अनचाहे त्रुटियां डेटा दूषित हो जाती हैं और प्रोग्राम को क्रैश होने का कारण बनता है। – josefx

3

आप फ़ंक्शन के त्रुटि-कोड-लौटने वाले संस्करणों का उपयोग करते हैं और वापसी मान के अनुसार कार्य करते हैं।

23

नहीं, विकल्प यह है कि लोगों ने सी में उम्र के लिए क्या किया है ... आप एक त्रुटि स्थिति कोड लौटाते हैं जो इंगित करता है कि फ़ंक्शन सफल हुआ या नहीं, और जिस तरीके से यह विफल हो सकता है, उसके आधार पर आप शायद एक या अधिक पैरामीटर्स हैं जिसमें आप जिस तरीके से असफल होते हैं इंगित करते हैं (या आप त्रुटि स्थिति कोड में विफलता के प्रकार को शामिल करते हैं, फिर यह मामला-दर-मामला चीज़ है)।

26

या आप थोड़ा और आगे पढ़ सकता है:

उनके चेहरे पर, अपवाद उपयोग कर के लाभ लागत, विशेष रूप से नई परियोजनाओं में पल्ला झुकना। हालांकि, मौजूदा कोड के लिए , अपवादों का परिचय सभी निर्भर कोड पर प्रभाव डालता है। यदि अपवाद एक नई परियोजना से परे प्रचारित हो सकते हैं, तो को नई अपवाद मुक्त कोड में नई परियोजना को एकीकृत करने के लिए समस्याग्रस्त हो जाता है। चूंकि अधिकांश Google पर मौजूदा C++ कोड अपवादों से निपटने के लिए तैयार नहीं है, तो अपवाद उत्पन्न करता है जो नया कोड अपनाने के लिए अपेक्षाकृत मुश्किल है।

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

अपवादों का उपयोग करने के खिलाफ हमारी सलाह दार्शनिक या नैतिक आधार पर व्यावहारिक नहीं है, बल्कि व्यावहारिक हैं। क्योंकि हम गूगल और पर हमारे खुला स्रोत परियोजनाओं का उपयोग करना चाहते यह अगर उन परियोजनाओं अपवाद उपयोग करें, हम आपको Google खुला स्रोत परियोजनाओं में अपवाद के खिलाफ सलाह की जरूरत है ऐसा करने के लिए मुश्किल है। चीजें शायद अलग होंगी यदि हमारे पास था जो इसे फिर से स्क्रैच से करने के लिए करता था।

विंडोज नियम के लिए इस नियम ( पन इरादा) के लिए अपवाद है।

+17

फिर भी Google पर काम नहीं करने का एक अन्य कारण। –

+5

क्यों? मैंने पूरी सी ++ शैली मार्गदर्शिका पढ़ी है और मैं पूरी तरह से टिप्पणियों से सहमत हूं –

+11

@ करेल: क्योंकि हम में से कुछ सी ++ को मौजूदा सी कोडबेस में नहीं जोड़ रहे हैं, और इसलिए रिपोर्टिंग त्रुटियों के लिए अपवादों का उपयोग करना चाहिए। Google स्टाइल गाइड स्टाइल और स्वरूपण और इस तरह के संबंध में ठीक है, लेकिन "हम केवल एक का उपयोग करते हैं सी ++ फीचर्स का सबसेट "टुकड़े नए कोड के लिए बस अच्छे विचार नहीं हैं, जब तक कि वह कोड लाइब्रेरी के लिए न हो जो नए कोड द्वारा उपभोग किया जाता है। –

6
जुड़ा हुआ स्टाइल गाइड

यह अच्छी तरह से बताते हैं:

उनके चेहरे पर, अपवाद उपयोग कर के लाभ, विशेष रूप से नई परियोजनाओं में लागत पल्ला झुकना। हालांकि, मौजूदा कोड के लिए , अपवादों का परिचय सभी निर्भर कोड पर प्रभाव डालता है। यदि अपवाद एक नई परियोजना से परे प्रचारित हो सकते हैं, तो को नई अपवाद मुक्त कोड में नई परियोजना को एकीकृत करने के लिए समस्याग्रस्त हो जाता है। चूंकि अधिकांश Google पर मौजूदा C++ कोड अपवादों से निपटने के लिए तैयार नहीं है, तो अपवाद उत्पन्न करता है जो नया कोड अपनाने के लिए अपेक्षाकृत मुश्किल है।

अपवादों का उपयोग किये बिना या अपवाद गारंटी के बारे में चिंता किए बिना मजबूत कोड बनाने के लिए सी ++ में अपेक्षाकृत आसान है। रिटर्न कोड और आवेषण के साथ, अपवाद वास्तव में प्रोग्रामर त्रुटियों तक ही सीमित हैं।

5

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

कई मौजूदा उत्तर दस्तावेज़ के रूप में, आप एक सेंटीनेल मान (जैसे एक सत्य/झूठी सफलता मान, एक enum) वापस कर सकते हैं। यह अभ्यास POSIX और libc द्वारा निर्दिष्ट सामान्य सी कार्यों से व्यापक रूप से परिचित है, जैसे fopen(), strstr() या printf()।

एक और महत्वपूर्ण विकल्प कुछ आंतरिक स्थिति निर्धारित करना है जिसे वे बाद में पूछ सकते हैं। आप क्यों चाहते हैं या उत्तरार्द्ध करने की आवश्यकता है? चूंकि कुछ फ़ंक्शंस, महत्वपूर्ण रूप से सी ++ कन्स्ट्रक्टर और ऑपरेटर, आपको आमतौर पर त्रुटि कोड वापस करने का अवसर नहीं देते हैं। उदाहरण के लिए, में:

 
    X x1(something), x2(whatever); 
    fn(x1 + x2); 

X::X(...) कुछ भी वापस नहीं कर सकता। X::operator+ (यह मानते हुए + रूपांतरण ऑपरेटरों के परिणामों पर लागू नहीं है) लागू किया जा सकता है, लेकिन fn() शायद एक const X& (या के साथ सी ++ 11 X&&), और operator+ जरूरतों की उम्मीद है एक X तो यह सफल स्थिति में काम करता है वापस जाने के लिए। आपके पास एक अलग प्रकार का त्रुटि कोड वापस करने का कोई मौका नहीं है। class X को कुछ आंतरिक स्थिति सेट करने की आवश्यकता हो सकती है कि अन्य कोड (शायद fn(), शायद fn() के बाद एक कथन कहा जाता है) उचित कार्रवाई करने के लिए परीक्षण। - कारणों अपवाद बनाए गए थे में से एक

X x1(something), x2(whatever); 
assert(x1.is_valid() and x2.is_valid()); 
X x3 = x1 + x2; 
assert(x3.is_valid()); 
fn(x3); 

ध्यान दें कि इस त्रुटि से निपटने सम्मेलन वर्बोज़ और अनदेखी की या ग्राहक कोडर द्वारा अनदेखा किया जा रहा की संभावना है:

तो, आप की तरह कुछ के साथ खत्म। इस पर एक दिलचस्प भिन्नता का उपयोग अधिकांश फ्लोट प्वाइंट हार्डवेयर द्वारा किया जाता है - 0 या अंडरफ्लो द्वारा विभाजन जैसे कुछ संचालन रजिस्टर को सेंटिनल मानों जैसे कि "नाएन" या +/- इन्फिनिटी, और फिर एक तर्क शामिल संचालन के रूप में सेट कर सकते हैं ऐसे राज्य में राज्य को उनके परिणाम के लिए प्रचारित करते हैं। उदाहरण के लिए, x = 8 + y/0; z = x + 2;z को एक सेंटीनेल पर भी सेट करेगा। यहां विचार यह है कि आप कोड लिख सकते हैं जो जब भी संभव हो सही परिणाम की गणना करता है, और परिणाम देखने से पहले एक बार जांचें कि यह देखने के लिए कि गणना कोड में कहीं से भी कोई त्रुटि उस परिणाम को अमान्य कर देती है या नहीं।यह कभी-कभी गणित कोड के लिए ठीक काम करता है, खासकर जब आप चर के मौजूदा मानों के आधार पर ब्रांचिंग निर्णय नहीं ले रहे हैं, लेकिन दुर्भाग्य से कई स्थितियों में आप या तो सक्षम नहीं होंगे या नहीं करेंगे त्रुटि राज्यों को संभालने और प्रसारित करने के लिए संभावित रूप से अमान्य ऑब्जेक्ट कोड सुपर-रक्षात्मक रूप से।

अपवादों के बिना सी ++ का उपयोग गंभीरता से उपयोगिता, रखरखाव, संयोजन और भाषा के लालित्य से समझौता करता है।

अपवाद उपयोग पर कुल प्रतिबंध के विकल्प के रूप में, कुछ वातावरण में आप अपने एपीआई की सीमाओं पर सभी अपवादों को पकड़ने में सक्षम हो सकते हैं, फिर "सी" शैली में त्रुटि कोड या सेंटीनेल मान वापस कर सकते हैं। यह आंतरिक रूप से बेहतर कोडिंग की अनुमति देता है, लेकिन बेहतर इंटरऑपरेबिलिटी बाहरी रूप से। अफसोस की बात है, कभी-कभी अपवादों का कोई भी उपयोग अव्यवहारिक होता है, क्योंकि आपका कोड ऐसे माहौल में निष्पादित होगा जहां अपवाद-हैंडलिंग तंत्र प्रदान नहीं किए जाते हैं ... शायद एक कर्नेल, ड्राइवर या एम्बेडेड वातावरण के अंदर एक स्ट्रिप डाउन सी ++ - स्टाइल कंपाइलर के साथ। हालांकि ऐसा वातावरण सच सी ++ नहीं है, क्योंकि यह मानक अनुपालन नहीं है।

6

अन्य अपवाद के विकल्प वापसी कोड से:

  • लिस्प शैली सशर्त हैंडलर।
  • सॉफ्टवेयर सिग्नल और स्लॉट, क्यूटी-शैली।
  • हार्डवेयर इंटरप्ट या सिग्नल हैंडलर बिना किसी स्टैक को खोलें। यह ढेर है कि एम्बेडेड उपकरणों पर अपवादों के साथ समस्या है।
  • longjmp/setjmp
  • कॉलबैक समारोह
  • करें मूल्य उदा errorno (यूनिक्स), GetLastError (विंडोज़), glGetError (ओपनजीएल), आदि
  • संदेश कतार, यदि कार्यक्रम संचालित होता है
  • उत्परिवर्ती मजेदार। इनपुट-आउटपुट पैरामीटर के रूप में हैंडलर ऑब्जेक्ट, त्रुटि पर सूचक बदल जाता है।
  • रेशे या कोई त्रुटि संकल्प के साथ धागे सह दिनचर्या
  • एएसएम __int 3 या सीपीयू बराबर
  • ओवरले निर्देश या ट्रैम्पोलिन कार्य करता है।

... और बहुत कुछ। उपर्युक्त सूचीबद्ध कई डिवाइस एम्बेडेड डिवाइस अनुकूल हैं।

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