यदि मैं assert()
का उपयोग करता हूं और दावा विफल रहता है तो assert()
abort()
पर कॉल करेगा, जो चल रहे प्रोग्राम को अचानक समाप्त कर देगा। मैं अपने उत्पादन कोड में बर्दाश्त नहीं कर सकता। क्या रनटाइम में जोर देने का कोई तरीका है, फिर भी असफल दावों को पकड़ने में सक्षम होने के लिए मुझे उनके पास शानदार तरीके से संभालने का मौका मिला है?मैं abort() का उपयोग किये बिना() कैसे जोर दे सकता हूं?
उत्तर
हां, वास्तव में ऐसा है। आपको कस्टम एक्टर्ट फ़ंक्शन स्वयं लिखना होगा, क्योंकि C++ के assert()
वास्तव में abort()
"फीचर" के साथ बंडल किया गया है। सौभाग्य से, यह आश्चर्यजनक रूप से सरल है।
Assert.hh
template <typename X, typename A>
inline void Assert(A assertion)
{
if(!assertion) throw X();
}
अगर एक विधेय नहीं रखता है ऊपर समारोह एक अपवाद फेंक देते हैं। इसके बाद आपको अपवाद पकड़ने का मौका मिलेगा। यदि आप अपवाद नहीं पकड़ते हैं, तो terminate()
कहा जाएगा, जो प्रोग्राम को abort()
के समान ही समाप्त कर देगा।
आप आश्चर्यचकित हो सकते हैं कि जब हम उत्पादन के लिए निर्माण कर रहे हैं तो दावा को दूर करने के बारे में क्या सोचते हैं। इस मामले में, आप स्थिरांक को परिभाषित कर सकते हैं जो दर्शाएगा कि आप उत्पादन के लिए निर्माण कर रहे हैं और फिर Assert()
पर निरंतर संदर्भित करें।
debug.hh
#ifdef NDEBUG
const bool CHECK_WRONG = false;
#else
const bool CHECK_WRONG = true;
#endif
main.cc
#include<iostream>
struct Wrong { };
int main()
{
try {
Assert<Wrong>(!CHECK_WRONG || 2 + 2 == 5);
std::cout << "I can go to sleep now.\n";
}
catch(Wrong e) {
std::cerr << "Someone is wrong on the internet!\n";
}
return 0;
}
हैं CHECK_WRONG
एक निरंतर तो Assert()
करने के लिए कॉल उत्पादन में दूर संकलित किया जाएगा, दावा है, भले ही है निरंतर अभिव्यक्ति नहीं। CHECK_WRONG
का जिक्र करते हुए इसमें थोड़ा सा नुकसान होता है, हम थोड़ा और टाइप करते हैं। लेकिन बदले में हम एक लाभ प्राप्त करते हैं कि हम विभिन्न समूहों के दावे को वर्गीकृत कर सकते हैं और उनमें से प्रत्येक को सक्षम और अक्षम कर सकते हैं जैसा कि हम फिट देखते हैं। इसलिए, उदाहरण के लिए हम ऐसे अनुमानों के समूह को परिभाषित कर सकते हैं जिन्हें हम उत्पादन कोड में भी सक्षम करना चाहते हैं, और फिर उन अनुमानों के समूह को परिभाषित करते हैं जिन्हें हम केवल विकास के निर्माण में देखना चाहते हैं।
Assert()
समारोह
if(!assertion) throw X();
टाइपिंग के बराबर है, लेकिन यह स्पष्ट रूप से प्रोग्रामर के इरादे इंगित करता है: एक अभिकथन बनाते हैं। सादे assert()
एस की तरह, इस दृष्टिकोण के साथ grep को भी सम्मिलित करना आसान है।
इस तकनीक के बारे में अधिक जानकारी के लिए Bjarne Stroustrup की सी ++ प्रोग्रामिंग भाषा 3e, खंड 24.3.7.2 देखें।
सी/सी ++ में आवेषण केवल डीबग बिल्ड में चलाए जाते हैं। तो यह रनटाइम पर नहीं होगा। सामान्य आवेषणों में चीजों को चिह्नित करना चाहिए कि यदि वे एक बग इंगित करते हैं, और आमतौर पर आपके कोड आदि में धारणाएं दिखाते हैं।
यदि आप कोड रखना चाहते हैं जो रनटाइम (रिलीज़ में) में त्रुटियों की जांच करता है तो आपको शायद अपवादों का उपयोग करना चाहिए इस तरह के रूप में दावा किया जाता है कि वे क्या करने के लिए डिजाइन किए गए हैं। आपका जवाब मूल रूप से वाक्यविन्यास पर जोर देने के लिए एक अपवाद फेंक देता है। हालांकि यह काम करेगा, इस पर कोई विशेष लाभ नहीं है कि मैं केवल अपवाद को पहले स्थान पर फेंकने पर देख सकता हूं।
उत्पादन निर्माण में चल रहे या चलने वाले आवेषण एक कंपाइलर विकल्प नहीं है। ऑप्टिमाइज़ेशन विकल्पों के बावजूद वे निश्चित रूप से डिफ़ॉल्ट रूप से जीसीसी में चलते हैं। –
मुझे व्यक्तिगत रूप से रिहाई मोड में आवेषण रखने का अच्छा विचार मिलता है। जब आप अपने क्लाइंट ऐप का उपयोग करते हैं तो आप यादृच्छिक दुर्घटनाओं को पसंद कर सकते हैं ... –
विशेष रूप से यदि आपका प्रोग्राम अपरिभाषित व्यवहार का कारण बनता है तो वह दावा गलत हो जाता है; यह ग्राहक को कम से कम एक मूल्यवान त्रुटि संदेश और आसान प्रजनन कदम देने की अनुमति देगा; इस पर विचार करना पहले कभी नहीं हुआ था; और आपने सोचा (और गारंटी) यह नहीं होगा। – dcousens
glib's error reporting functions एक जोर के बाद जारी रखने का दृष्टिकोण ले लो। ग्लिब अंतर्निहित प्लेटफॉर्म आजादी लाइब्रेरी है जो जीनोम (जीटीके के माध्यम से) का उपयोग करता है। यहां एक मैक्रो है जो पूर्व शर्त की जांच करता है और पूर्व शर्त विफल होने पर एक स्टैक ट्रेस प्रिंट करता है।
char *doSomething(char *ptr)
{
RETURN_VAL_IF_FAIL(ptr != NULL, NULL); // same as assert(ptr != NULL), but returns NULL if it fails.
if(ptr != NULL) // Necessary if you want to define the macro only for debug builds
{
...
}
return ptr;
}
void doSomethingElse(char *ptr)
{
RETURN_IF_FAIL(ptr != NULL);
}
:
void print_stack_trace(int fd)
{
void *array[256];
size_t size;
size = backtrace (array, 256);
backtrace_symbols_fd(array, size, fd);
}
इस तरह आप मैक्रो का उपयोग होता है:
#define RETURN_IF_FAIL(expr) do { \
if (!(expr)) \
{ \
fprintf(stderr, \
"file %s: line %d (%s): precondition `%s' failed.", \
__FILE__, \
__LINE__, \
__PRETTY_FUNCTION__, \
#expr); \
print_stack_trace(2); \
return; \
}; } while(0)
#define RETURN_VAL_IF_FAIL(expr, val) do { \
if (!(expr)) \
{ \
fprintf(stderr, \
"file %s: line %d (%s): precondition `%s' failed.", \
__FILE__, \
__LINE__, \
__PRETTY_FUNCTION__, \
#expr); \
print_stack_trace(2); \
return val; \
}; } while(0)
यहाँ समारोह है कि स्टैक ट्रेस प्रिंट, एक वातावरण के लिए लिखा जीएनयू toolchain (जीसीसी) का उपयोग करता है है
@ विल्हेल्मटेल I मान लीजिए कि यह अब तक का सबसे अच्छा समाधान है क्योंकि मैं अपवाद का उपयोग करने से असहमत हूं। असाधारण कुछ असाधारण के लिए होना चाहिए, हालांकि असर संभालना नहीं है। इसके अलावा, अगर आप रिलीज बिल्ड में एस्सर्ट ऑन छोड़ने की योजना बनाते हैं, जो मुझे लगता है कि जब तक प्रदर्शन महत्वपूर्ण नहीं है, तो यह विधि अधिक कुशल होगी। आप इसे वैयक्तिकृत भी कर सकते हैं ताकि ऐसा होने पर आपके प्रोग्राम को बाहर निकलने की आवश्यकता न हो और आपको जानकारी वापस मिल जाएगी। मैं आवेषण और अपवादों पर व्यावहारिक प्रोग्रामर पुस्तक के अध्याय को पढ़ने पर सुझाव देता हूं। इसके अलावा [यह लिंक] (http://www.gotw.ca/publications/mill22.htm)। – ForceMagic
यहाँ क्या मैं अपने में "assert.h" है है (मैक ओएस 10.4):
#define assert(e) ((void) ((e) ? 0 : __assert (#e, __FILE__, __LINE__)))
#define __assert(e, file, line) ((void)printf ("%s:%u: failed assertion `%s'\n", file, line, e), abort(), 0)
उस पर आधारित, कॉल को एक फेंक (अपवाद) द्वारा abort() को प्रतिस्थापित करें। और printf के बजाय आप स्ट्रिंग को अपवाद के त्रुटि संदेश में प्रारूपित कर सकते हैं। अंत में, आपको कुछ ऐसा मिलता है:
#define assert(e) ((void) ((e) ? 0 : my_assert (#e, __FILE__, __LINE__)))
#define my_assert(e, file, line) (throw std::runtime_error(\
std::string(file:)+boost::lexical_cast<std::string>(line)+": failed assertion "+e))
मैंने इसे संकलित करने की कोशिश नहीं की है, लेकिन आपको इसका अर्थ मिल गया है।
नोट: आपको यह सुनिश्चित करना होगा कि "अपवाद" हेडर हमेशा शामिल है, साथ ही बूस्ट (यदि आप त्रुटि संदेश स्वरूपण के लिए इसका उपयोग करने का निर्णय लेते हैं)। लेकिन आप "my_assert" को एक फ़ंक्शन भी बना सकते हैं और केवल इसके प्रोटोटाइप की घोषणा कर सकते हैं। की तरह कुछ:
void my_assert(const char* e, const char* file, int line);
और यह कहीं न कहीं लागू जहां आप स्वतंत्र रूप से सभी हेडर की आवश्यकता शामिल कर सकते हैं।
अगर आपको इसकी आवश्यकता है तो इसे #ifdef DEBUG में लपेटें, या नहीं, यदि आप हमेशा उन चेक को चलाने के लिए चाहते हैं।
तो यह तर्क देना बाकी है कि एक मैक्रो टेम्पलेट फ़ंक्शन से बेहतर है या नहीं। इसके अलावा, अनुक्रम ऑपरेटर का अर्थ है कि ऑपरेंड किसी भी मनमाने ढंग से क्रम में किया जा सकता है। मुझे संदेह है कि __asert() में आपका क्या मतलब है। – wilhelmtell
पहले ब्लॉक में "__assert" फ़ंक्शन मेरे सिस्टम हेडर (0 एस 10.4) से आता है, मुझे उम्मीद है कि वे जानते हैं कि वे क्या कर रहे हैं। मैक्रो फ़ाइल और लाइन जानकारी प्राप्त करना आसान बनाता है। लेकिन किसी बिंदु पर यह काफी कॉस्मेटिक हो जाता है ... – rlerallut
_set_error_mode(_OUT_TO_MSGBOX);
मेरा मानना है कि यह कार्य आपकी मदद कर सकता है।
यह विंडोज़ केवल एक समारोह प्रतीत होता है: [लिंक] (https://msdn.microsoft.com/en-us/library/aa235388 (v = vs.60)। एएसपीएक्स) –
और कम से कम आपको यह समझाना चाहिए कि हेडर/कंपाइलर/इसका उपयोग करने के लिए जो भी आवश्यक है। –
आप दावे के बारे में जानकारी के साथ एक चरित्र स्ट्रिंग फेंक करना चाहते हैं: http://xll8.codeplex.com/SourceControl/latest#xll/ensure.h
- 1. मैं पायथन सी कोड से कैसे जोर दे सकता हूं?
- 2. मैं lstlisting के हिस्सों पर जोर कैसे दे सकता हूं?
- 3. मैं चयनकर्ताओं का उपयोग किये बिना jQuery ऑब्जेक्ट्स को कैसे समूहित कर सकता हूं?
- 4. मैं लूप का उपयोग किये बिना पूरी तरह से हैश को रीसेट कैसे कर सकता हूं?
- 5. जावास्क्रिप्ट का उपयोग किये बिना मैं HTML में मेनू कैसे बना सकता हूं?
- 6. मैं CPAN.pm का उपयोग किये बिना पर्ल मॉड्यूल कैसे स्थापित कर सकता हूं?
- 7. सूचियों मॉड्यूल का उपयोग किये बिना मैं एर्लांग की सूची concatenate कैसे लिख सकता हूं?
- 8. मैं माउस का उपयोग किये बिना इंटेलिजे में एक नई कक्षा कैसे बना सकता हूं?
- 9. मैं Invoke विधि का उपयोग किये बिना दो लैम्ब्डा अभिव्यक्तियों को कैसे जोड़ सकता हूं?
- 10. WinMain का उपयोग किये बिना मैं विंडोज़ एप्लिकेशन कैसे लिख सकता हूं?
- 11. पर्ल में लूप का उपयोग किये बिना मैं सरणी को कैसे फ़िल्टर कर सकता हूं?
- 12. मैं HttpContext का उपयोग किये बिना वेब एप्लिकेशन की वर्तमान कॉन्फ़िगरेशन कैसे प्राप्त कर सकता हूं?
- 13. सदस्यता.GetUser() का उपयोग किये बिना मैं एएसपी.NET सदस्यता में UserId तक कैसे पहुंच सकता हूं?
- 14. क्या मैं मध्य-क्लिक का उपयोग किये बिना आसानी से एक्सेल स्क्रॉल कर सकता हूं?
- 15. अपने विचारों का उपयोग किये बिना सुरक्षित सेवाओं का उपयोग
- 16. oauth-php लाइब्रेरी का उपयोग किये बिना मैं OAuth और PHP का उपयोग कैसे कर सकता हूं?
- 17. क्या मैं इंटरफ़ेस मानों का एक टुकड़ा जोर दे सकता हूं?
- 18. मैं आरएसपीसी के साथ व्यवहार शुरू करने पर कैसे जोर दे सकता हूं?
- 19. डेटाबेस का उपयोग किये बिना गतिशील एएसपी.NET उपयोगकर्ता नियंत्रण को मैं फिर से चालू कैसे कर सकता हूं?
- 20. जावास्क्रिप्ट का उपयोग किये बिना लिंक की तरह दिखने के लिए मैं एक अवधि कैसे बना सकता हूं?
- 21. बाहरी DLL या रनटाइम्स का उपयोग किये बिना मैं बड़ी फ़ाइल को कैसे संकुचित और एन्क्रिप्ट कर सकता हूं?
- 22. ग्राफ़िक्स ऑब्जेक्ट का उपयोग किये बिना स्ट्रिंग को मापें?
- 23. मार्गों का उपयोग किये बिना Ember.js में राज्य?
- 24. क्या मैं जोर से() उपयोग गलत समझ रहा हूं?
- 25. मैं imagecolorallocate को रंग कैसे दे सकता हूं?
- 26. फॉर्म्स प्रमाणीकरण का उपयोग करके मैं यूआरएल में अज्ञात पहुंच कैसे दे सकता हूं?
- 27. कैसे wget abort?
- 28. मैं तालिका का उपयोग किये बिना इस 3 कॉलम लेआउट को दोहराना कैसे करूं?
- 29. मैं स्मृति त्रुटियों के बिना var_dump + आउटपुट बफरिंग का उपयोग कैसे कर सकता हूं?
- 30. फ्लैश ऑथरिंग टूल का उपयोग किये बिना .fla फ़ाइल खोलें
आप ही कभी मिल का निर्माण अपवाद डिफ़ॉल्ट, वहाँ नहीं इस के लिए बहुत कुछ कर सकते हैं लाभ है के बाद से जब से तुम के लिए किसी भी रन टाइम डाटा परिवहन नहीं कर सकते पकड़ साइट ... –
इसे int बनाने के बजाए जोर तर्क को templatizing का जोड़ा मूल्य क्या है? वैसे भी अंततः int में परिवर्तित होना होगा। – JohnMcG
@ ग्रेग रोजर्स बजेर्न स्ट्राउस्ट्रप आपके द्वारा उल्लिखित समस्या का समाधान प्रदान करता है: आप एक अनुकूलित ऑब्जेक्ट जोड़ सकते हैं जिसे आप Assert() के अतिरिक्त पैरामीटर के रूप में फेंकना चाहते हैं। नकारात्मकता यह है कि अतिरिक्त पैरामीटर के कारण Assert() अब assert() की तरह नहीं लगेगा। – wilhelmtell