मैं रिलीज सी बिल्ड्स के प्रदर्शन को प्रभावित किए बिना डिबगिंग को आसान बनाने के लिए अपने सी ++ कोड में बहुत सारे दावे जोड़ देता हूं। अब, assert
सी ++ तंत्रों को ध्यान में रखे बिना शुद्ध सी मैक्रो है।
दूसरी ओर सी ++ परिभाषित करता है std::logic_error
, जिसका मतलब उन मामलों में है जहां कार्यक्रम के तर्क में त्रुटि है (इसलिए नाम)। एक उदाहरण फेंकना सिर्फ सही हो सकता है, और अधिक C ++ ish विकल्प assert
।
समस्या यह है कि assert
और abort
दोनों विध्वंसक को बुलाए बिना कार्यक्रम को तुरंत समाप्त कर देते हैं, इसलिए सफाई को छोड़ देते हैं, जबकि एक अपवाद को मैन्युअल रूप से फेंकने से अनावश्यक रनटाइम लागत में वृद्धि होती है। इसके चारों ओर एक तरह से एक स्वयं के स्थूल मैक्रो का निर्माण होगा SAFE_ASSERT
, जो सी समकक्ष की तरह काम करता है, लेकिन विफलता पर एक अपवाद फेंकता है।
मैं इस समस्या पर तीन राय सोच सकता हूं:
- C के मुखर से चिपके रहें। चूंकि कार्यक्रम तुरंत समाप्त हो गया है, इससे कोई फर्क नहीं पड़ता कि परिवर्तन सही ढंग से अनियंत्रित हैं या नहीं। इसके अलावा,
#define
C ++ में s का उपयोग करना उतना ही बुरा है। - एक अपवाद को फेंक दें और इसे मुख्य () में पकड़ लें । प्रोग्राम के किसी भी राज्य में विध्वंसक को छोड़ने के लिए कोडिंग करना बुरी प्रथा है और इसे हर कीमत पर टाला जाना चाहिए, और इसलिए कॉल को समाप्त किया जाना चाहिए ()। यदि अपवादों को फेंक दिया जाता है, तो उन्हें पकड़ा जाना चाहिए।
- एक अपवाद फेंकें और इसे कार्यक्रम को समाप्त करने दें। एक कार्यक्रम को समाप्त करने वाला एक अपवाद ठीक है, और इसके कारण
NDEBUG
, रिलीज बिल्ड में ऐसा कभी नहीं होगा। पकड़ना अनावश्यक है और आंतरिक कोड के कार्यान्वयन के विवरण को उजागर करता हैmain()
।
क्या इस समस्या का कोई निश्चित जवाब है? कोई पेशेवर संदर्भ?
संपादित: लंघन विध्वंसक, निश्चित रूप से, कोई अपरिभाषित व्यवहार नहीं है।
static_assert
जहां यह आपके पास उपलब्ध हो तो उचित है।
std::bug
?
std::abort()
; यह सिर्फ एक संकेत देगा जो प्रक्रिया को समाप्त करने का कारण बनता है।
logic_error
तर्क त्रुटि है। कार्यक्रम के तर्क में त्रुटि को बग कहा जाता है। आप अपवादों को फेंककर बग को हल नहीं करते हैं।