मुखर में कस्टम संदेश जोड़ें?


129

क्या मुखर द्वारा फेंके गए संदेश को जोड़ने या संपादित करने का कोई तरीका है? मैं कुछ का उपयोग करना चाहते हैं

assert(a == b, "A must be equal to B");

फिर, संकलक लाइन , समय और इतने पर जोड़ता है ...

क्या यह संभव है?


आप एक मैक्रो को इस तरह परिभाषित कर सकते हैं ।
HelloGoodbye

जवाबों:


240

एक हैक जो मैंने देखा है वह &&ऑपरेटर का उपयोग करना है। चूंकि एक पॉइंटर "सच है" यदि यह गैर-अशक्त है, तो आप स्थिति में बदलाव किए बिना निम्नलिखित कर सकते हैं:

assert(a == b && "A is not equal to B");

चूंकि assertजो स्थिति विफल रही, वह आपके संदेश को भी प्रदर्शित करेगी। यदि यह पर्याप्त नहीं है, तो आप अपना स्वयं का myAssertफ़ंक्शन या मैक्रो लिख सकते हैं, जो आप चाहते हैं।


27
एक अन्य विकल्प ऑपरेंड्स को उल्टा करना और कॉमा ऑपरेटर का उपयोग करना है। आपको अतिरिक्त कोष्ठक की आवश्यकता है, इसलिए अल्पविराम को तर्कों के बीच एक सीमांकक के रूप में नहीं माना जाता है:assert(("A must be equal to B", a == b));
कीथ थॉम्पसन

3
यह अच्छा होगा, हालांकि, चर के मूल्यों को मुद्रित करने में सक्षम होने के लिए, जैसा कि:assert(a == b && "A (" << A << ") is not equal to B (" << B << ")");
फ्रैंक

7
@ फ्रेंक, printfअगर कुछ भी छापता है तो एक गैर-शून्य मान लौटाता है, इसलिए आप कुछ ऐसा कर सकते हैं assert(a == b && printf("a (%i) is not equal to b (%i)", a, b)), हालांकि उस बिंदु पर आपको संभवतः अपना स्वयं का आवरण लिखना चाहिए।
जंक

1
बुरा कोड! मुझे यह समझ में नहीं आता है! यदि a == b गलत है, और अभिव्यक्ति भी झूठी होनी चाहिए, और, इसलिए, स्ट्रिंग का मूल्यांकन नहीं किया जाना चाहिए।
राग

1
@TUIlover, यह नहीं है कि C स्ट्रिंग शाब्दिक कैसे काम करते हैं; वे संकलित समय-स्थिरांक हैं और इस संदर्भ में उनका उपयोग तुच्छ रूप से अनुकूलित है। कोई रनटाइम लागत नहीं है।
zneak

45

एक अन्य विकल्प ऑपरेंड्स को उल्टा करना और कॉमा ऑपरेटर का उपयोग करना है। आपको अतिरिक्त कोष्ठक की आवश्यकता है, इसलिए अल्पविरामों को तर्कों के बीच एक सीमांकक के रूप में नहीं माना जाता है:

assert(("A must be equal to B", a == b));

(यह बेहतर दृश्यता के लिए उपरोक्त टिप्पणियों से कॉपी किया गया था)


3
यह एक महान दृष्टिकोण है, एक छोटे से मुद्दे के साथ, यह "चेतावनी प्रदर्शित करेगा: कॉमा ऑपरेटर के बाएं ऑपरेंड का कोई प्रभाव नहीं है" जब जी ++ में संकलित किया जाता है -व्यूज्ड-वैल्यू
v010dya

1
या किसी मैक्रो के साथ: #ifndef m_assert #define m_assert (expr, msg) ज़ोर ((संदेश, expr)) #endif
ज़ीमॉन Marczak

मैक्रो रैपर का उपयोग करने से आप gcc की चेतावनी से बच सकते हैं:#define m_assert(expr, msg) assert(( (void)(msg), (expr) ))
Jander

25

यहाँ मुखर मैक्रो का मेरा संस्करण है, जो संदेश को स्वीकार करता है और सब कुछ स्पष्ट तरीके से प्रिंट करता है:

#include <iostream>

#ifndef NDEBUG
#   define M_Assert(Expr, Msg) \
    __M_Assert(#Expr, Expr, __FILE__, __LINE__, Msg)
#else
#   define M_Assert(Expr, Msg) ;
#endif

void __M_Assert(const char* expr_str, bool expr, const char* file, int line, const char* msg)
{
    if (!expr)
    {
        std::cerr << "Assert failed:\t" << msg << "\n"
            << "Expected:\t" << expr_str << "\n"
            << "Source:\t\t" << file << ", line " << line << "\n";
        abort();
    }
}

अब, आप इसका उपयोग कर सकते हैं

M_Assert(ptr != nullptr, "MyFunction: requires non-null argument");

और विफलता के मामले में आपको इस तरह एक संदेश मिलेगा:

मुखर विफल: MyFunction: को गैर-अशक्त तर्क की आवश्यकता है

उम्मीद: ptr! = Nullptr

स्रोत: C: \ MyProject \ src.cpp, पंक्ति 22

अच्छा और साफ, अपने कोड में इसका उपयोग करने के लिए स्वतंत्र महसूस करें =)


अच्छा है। बहुत उपयोगी
किलर

मैं थोड़ा उलझन में हूँ। क्या प्रत्यक्ष प्रतिस्थापन के लिए #Expr को एक स्ट्रिंग के रूप में माना जाता है? #Expr और Expr में क्या अंतर है?
मिन्ह ट्रैन

@MinhTran मान लें कि आपकी मुखर स्थिति है x == y। तब Expr में विस्तार होगा if( !(x == y))और यह वह जगह है जहाँ स्थिति की जाँच की जाती है, और #Expr स्ट्रिंग शाब्दिक में विस्तारित होगी "x == y", जिसे हम फिर त्रुटि संदेश में डालते हैं।
यूजीन मैग्डलिट्स

दुर्भाग्य से, यह समाधान आरक्षित पहचानकर्ताओं का उपयोग करने के कारण अपरिभाषित व्यवहार का कारण बनता है।
मोनिका

19
BOOST_ASSERT_MSG(expre, msg)

http://www.boost.org/doc/libs/1_51_0/libs/utility/assert.html

आप या तो सीधे उपयोग कर सकते हैं या बूस्ट कोड को कॉपी कर सकते हैं। यह भी ध्यान दें कि बूस्ट एस्टर केवल हेडर है, इसलिए यदि आप सभी बूस्ट को स्थापित नहीं करना चाहते हैं, तो आप उस सिंगल फाइल को ले सकते हैं।


@ जिचाओ, मुखर अंतरफलक को लागू करने से आपका क्या मतलब है?
टार्क

7

जैसा कि zneak का उत्तर कोड को कुछ हद तक समझाता है, एक बेहतर तरीका यह है कि आप जिस स्ट्रिंग टेक्स्ट के बारे में बात कर रहे हैं, उस पर टिप्पणी करें। अर्थात।:

assert(a == b); // A must be equal to B

चूँकि एसेरर एरर का रीडर एरर मैसेज से किसी भी तरह फाइल और लाइन को देखेगा, वे यहाँ पूरा विवरण देखेंगे।

क्योंकि, दिन के अंत में, यह:

assert(number_of_frames != 0); // Has frames to update

इससे बेहतर पढ़ता है:

assert(number_of_frames != 0 && "Has frames to update");

कोड के मानव पार्सिंग के संदर्भ में। पठनीयता। साथ ही लैंग्वेज हैक भी नहीं।


1
"चूंकि मुखर त्रुटि के पाठक फ़ाइल और लाइन को वैसे भी त्रुटि संदेश से देखेंगे," - केवल अगर वे मेहनती हैं।
जेसन एस

केवल अगर वे आपके द्वारा लगाए गए बग को ठीक करना चाहते हैं ... तो एक मूर्खतापूर्ण टिप्पणी
मेटामोर्फोसिस

1
नहीं। आप लोगों को समस्या को देखने के लिए जितना आसान बनाते हैं, उतनी ही अधिक वे कार्रवाई करेंगे।
जेसन एस

श्रग असहमत।
कायापलट

2

मुखर मैक्रो / फ़ंक्शन संयोजन है। आप अपने स्वयं के फ़ंक्शन के साथ अपने स्वयं के मैक्रो / फ़ंक्शन, उपयोग , आदि को परिभाषित कर सकते हैं __FILE__, जो एक कस्टम संदेश लेता है__BASE_FILE____LINE__


-6

Vc के लिए, assert.h में निम्न कोड जोड़ें,

#define assert2(_Expression, _Msg) (void)( (!!(_Expression)) || (_wassert(_CRT_WIDE(#_Msg), _CRT_WIDE(__FILE__), __LINE__), 0) )

11
अपने संकलक के हेडर को संशोधित करना बुरा विचार है।
रॉस रिज
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.