"मुखर" फ़ंक्शन क्या है?


261

मैं ओपनसीवी ट्यूटोरियल का अध्ययन कर रहा हूं और पूरे assertसमारोह में आया हूं; यह क्या करता है?


20
ध्यान दें कि आदमी मुखर से नोट करता है: "assert () को मैक्रो के रूप में लागू किया जाता है; यदि परीक्षण की गई अभिव्यक्ति के साइड-इफेक्ट्स हैं, तो NDEBUG परिभाषित होने के आधार पर प्रोग्राम का व्यवहार अलग होगा। यह हाइजेनबग्स बना सकता है जो डीबगिंग चालू होने पर चले जाते हैं। । "
जोहान्स शाउब -


35
@ S.Lott अब Google पर खोज करने वाले लोग इस पृष्ठ को शीर्ष खोज परिणामों में से एक के रूप में पाएंगे, एक अच्छा सहकर्मी अपने प्रश्न का उत्तर देने के लिए, और एक ही समय में स्टैक ओवरफ़्लो को बढ़ावा दे रहा है, इसलिए यह मेरे से +1 है!
मैट ग्रम

6
यह मुझसे 1 है। शीर्ष खोज परिणाम प्रलेखन होना चाहिए जिसे ओपी को पहले स्थान पर परामर्श करना चाहिए।
को ऑर्बिट

9
@LightnessRacesinOrbit। मुझे आलसी कहो, लेकिन मैं उत्कृष्ट संघनित, संक्षेपित, और प्रलेखन की रीडिंग का उपयोग करना पसंद करता हूं जो कि ज्ञानी एसओ जैसे उपयोगकर्ता स्वयं प्रदान करते हैं। मेरा हार्दिक धन्यवाद :)
Tyson Hilmer

जवाबों:


297

assertकार्यक्रम को समाप्त कर देगा (आमतौर पर एक संदेश के साथ मुखर कथन का हवाला देते हुए) यदि इसका तर्क गलत है। यह आमतौर पर डिबगिंग के दौरान उपयोग किया जाता है ताकि अप्रत्याशित स्थिति उत्पन्न होने पर कार्यक्रम को अधिक स्पष्ट रूप से विफल किया जा सके।

उदाहरण के लिए:

assert(length >= 0);  // die if length is negative.

यदि आप ऐसा करते हैं तो आप एक अधिक सूचनात्मक संदेश भी प्रदर्शित कर सकते हैं:

assert(length >= 0 && "Whoops, length can't possibly be negative! (didn't we just check 10 lines ago?) Tell jsmith");

वरना इस तरह:

assert(("Length can't possibly be negative! Tell jsmith", length >= 0));

जब आप एक रिलीज़ (गैर-डिबग) बिल्ड कर रहे होते हैं, तो आप मैक्रो assertको परिभाषित करके NDEBUG, आमतौर पर एक कंपाइलर स्विच के साथ बयानों के मूल्यांकन के ओवरहेड को भी हटा सकते हैं । इस बात की पुष्टि यह है कि आपके प्रोग्राम को कभी भी स्थूल मैक्रो के चलने पर भरोसा नहीं करना चाहिए ।

// BAD
assert(x++);

// GOOD
assert(x);    
x++;

// Watch out! Depends on the function:
assert(foo());

// Here's a safer way:
int ret = foo();
assert(ret);

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


49
" assertआमतौर पर एक अपवाद उठाता है" - सी ++ में यह "अपवाद" नहीं उठता है इसे गर्भपात कहते हैं ... यह थोड़ा अलग है।
आर्टीम

5
मुझे नहीं लगता कि यह उत्तर उन्हीं भाषाओं के बारे में है जैसे प्रश्न टैग किए गए हैं (C और C ++)। सी और सी ++ में, एसिस्टर एक अपवाद नहीं उठाता है, इसके तर्क के आसपास कोष्ठक हैं, और #चरित्र एक टिप्पणी पेश नहीं करता है।
11:17 पर स्टीव जेसप

यहां आपके विकल्प हैं: उत्तर समुदाय-विकी बनाएं और पुराने सामान को हटाने के लिए अपना प्रश्न संपादित करें, दूसरों को सही जानकारी देने के लिए कहें। इस तरह, डाउनवोट्स आपके प्रतिनिधि को प्रभावित नहीं करेंगे, और लोग उत्तर को सुधार सकते हैं।
जोहान्स शाउब -

2
लंबाई> = 0 भी झूठी निकलेगी यदि लंबाई NaN है
Andreas

1
वर्तमान में, वीएस 2015 में, त्रुटि संदेश के साथ मुखर काम नहीं करेगा क्योंकि यह क्रम से बाहर है। यह होना चाहिएassert("error message", expression)
Dooskington

102

ज़ोर कंप्यूटर कथन के अनुरूप है सुनिश्चित करें कि अंग्रेजी में।


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

7
@ ल्यूक, जो अंग्रेजी भाषा के चमत्कार को दिखाता है, उस भाषा में एक ही बात कहने के कई तरीके प्रदान किए जाते हैं। लेकिन मुखर (लंबाई> 0) पर विचार करें। इसलिए हम अनुवाद कर सकते हैं कि "लंबाई की जांच शून्य से अधिक है" या "यह सुनिश्चित करें कि लंबाई शून्य से अधिक है" । जबकि स्पष्ट रूप से दोनों विकल्प काम करते हैं, मैं अभी भी उन्हें पसंद करता हूं;)
ब्लेक 7

4
ठीक है, लेकिन अन्य व्याख्या "है बनाने लंबाई शून्य से अधिक होना।" इसलिए थोड़ी अधिक अस्पष्टता है।
ल्यूक मौरर

29
यह अंग्रेजी क्रिया "जोर" के अधिक निकट है
स्टीव कार्टर

वास्तव में, "सुनिश्चित करें" की व्याख्या "चेक के रूप में की जा सकती है, और यदि ठीक नहीं है, तो बदलें"।
एरिक बॉन्जर्स

14

पर एक नज़र डालें

Assert () C ++ में उदाहरण कार्यक्रम

कई संकलक एक मुखर () मैक्रो प्रदान करते हैं। मुखर () मैक्रो TRUE लौटाता है यदि इसका पैरामीटर TRUE का मूल्यांकन करता है और यदि FALSE का मूल्यांकन करता है तो यह किसी प्रकार की कार्रवाई करता है। कई कंपाइलर प्रोग्राम को एक एस्टर () पर निरस्त कर देंगे जो विफल हो जाता है; दूसरों को एक अपवाद फेंक देंगे

मुखर () मैक्रो की एक शक्तिशाली विशेषता यह है कि प्रीप्रोसेसर इसे किसी भी कोड में ध्वस्त कर देता है यदि DEBUG परिभाषित नहीं है। यह विकास के दौरान एक बड़ी मदद है, और जब अंतिम उत्पाद जहाजों में कोई प्रदर्शन जुर्माना नहीं होता है और न ही कार्यक्रम के निष्पादन योग्य संस्करण के आकार में वृद्धि होती है।

उदाहरण के लिए

#include <stdio.h>
#include <assert.h>

void analyze (char *, int);

int main(void)
{
   char *string = "ABC";
   int length = 3;

   analyze(string, length);
   printf("The string %s is not null or empty, "
          "and has length %d \n", string, length);
}

void analyze(char *string, int length)
{
   assert(string != NULL);     /* cannot be NULL */
   assert(*string != '\0');    /* cannot be empty */
   assert(length > 0);         /* must be positive */
}

/****************  Output should be similar to  ******************
The string ABC is not null or empty, and has length 3

11
यदि "NDEBUG को परिभाषित किया गया है तो" नहीं होना चाहिए?
रिचएन

2
क्या है कि "कई संकलक" के बारे में? MSVC और GCC दोनों इस एक के अनुरूप हैं। कौन से गैर-अनुपालन संकलक: मुखर नहीं हैं; जब कोई मुखर विफल हो जाए तो संदेश न छापें और न ही निरस्त करें उचित NDEBUG के बजाय DEBUG का उपयोग करें?
11:17 पर स्टीव जेसप

लामो, बेशक यह जावा-सैंपल नामक एक वेबसाइट है जो इसे इतना गलत हो जाता है।
अंडरस्कोर_ड

6

मुखर () फ़ंक्शन प्रोग्राम बग का निदान कर सकता है। C में, इसे में परिभाषित किया गया है <assert.h>, और C ++ में इसे परिभाषित किया गया है <cassert>। इसका प्रोटोटाइप है

void assert(int expression);

तर्क अभिव्यक्ति कुछ भी हो सकता है जिसे आप परीक्षण करना चाहते हैं - एक चर या कोई सी अभिव्यक्ति। यदि अभिव्यक्ति TRUE का मूल्यांकन करती है, तो मुखर () कुछ नहीं करता है। यदि अभिव्यक्ति FALSE का मूल्यांकन करती है, तो एस्टर () stderr पर त्रुटि संदेश प्रदर्शित करता है और प्रोग्राम निष्पादन को रोक देता है।

आप मुखर () का उपयोग कैसे करते हैं? यह अक्सर प्रोग्राम बग्स को ट्रैक करने के लिए उपयोग किया जाता है (जो संकलन त्रुटियों से अलग हैं)। बग किसी प्रोग्राम को संकलित करने से नहीं रोकता है, लेकिन यह गलत परिणाम देने या अनुचित तरीके से (उदाहरण के लिए, लॉकिंग) को चलाने का कारण बनता है। उदाहरण के लिए, आपके द्वारा लिखा गया एक वित्तीय-विश्लेषण कार्यक्रम कभी-कभी गलत उत्तर दे सकता है। आपको संदेह है कि समस्या एक नकारात्मक मूल्य पर परिवर्तनीय ब्याज_रेट के कारण होती है, जो कभी नहीं होनी चाहिए। इसे जांचने के लिए, कथन को रखें

मुखर (interest_rate> = 0); कार्यक्रम में उन स्थानों पर जहां interest_rate का उपयोग किया जाता है। यदि चर कभी नकारात्मक हो जाता है, तो मुखर () मैक्रो आपको सचेत करता है। आप समस्या के कारण का पता लगाने के लिए संबंधित कोड की जांच कर सकते हैं।

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

अभिकथन विफल: x, फ़ाइल सूची 19_3.c, पंक्ति 13 नोट करें कि, मुखर () काम करने के लिए, आपके प्रोग्राम को डिबग मोड में संकलित किया जाना चाहिए। डिबग मोड सक्षम करने के बारे में जानकारी के लिए अपने संकलक प्रलेखन का संदर्भ लें (जैसा कि एक क्षण में समझाया गया है)। जब आप बाद में रिलीज़ मोड में अंतिम संस्करण संकलित करते हैं, तो एस्टर () मैक्रो अक्षम हो जाते हैं।

 int x;

 printf("\nEnter an integer value: ");
 scanf("%d", &x);

 assert(x >= 0);

 printf("You entered %d.\n", x);
 return(0);

पूर्णांक मान दर्ज करें: 10

आपने १० में प्रवेश किया।

पूर्णांक मान दर्ज करें: -1

त्रुटि संदेश: असामान्य प्रोग्राम समाप्ति

आपका त्रुटि संदेश आपके सिस्टम और संकलक के आधार पर भिन्न हो सकता है, लेकिन सामान्य विचार समान है।


आपने बताया कि आपका नमूना कार्यक्रम मुखरता के साथ कैसे काम करता है। नहीं कि कैसे मुखर ही काम करता है। यह कार्यक्रम को असामान्य रूप से कैसे समाप्त करता है? क्या यह किसी प्रकार के अपवाद को फेंक देता है? किस प्रकार? क्या यह एक विशेष संकेत बनाता है? क्या संकेत है? क्या किसी भी तरह के C ++ ट्राइ-कैच मैकेनिज्म द्वारा जोर दिया जा सकता है?
मोति श्नोर

4

अपवादों को उठाता है ’और might हाल्ट का निष्पादन’ जैसी सामग्री अधिकांश संकलकों के लिए सही हो सकती है, लेकिन सभी के लिए नहीं। (BTW, वहाँ मुखर बयान है कि वास्तव में अपवाद फेंक रहे हैं?)

यहाँ c6x और अन्य TI संकलक द्वारा उपयोग किए जाने वाले मुखर का एक अलग, थोड़ा अलग अर्थ है: कुछ मुखर कथनों को देखने के बाद, ये संकलनक कुछ अनुकूलन करने के लिए उस कथन में जानकारी का उपयोग करते हैं। दुष्ट।

C में उदाहरण:

int dot_product(short *x, short *y, short z)
{
  int sum = 0
  int i;

  assert( ( (int)(x) & 0x3 ) == 0 );
  assert( ( (int)(y) & 0x3 ) == 0 );

  for( i = 0 ; i < z ; ++i )
    sum += x[ i ] * y[ i ];
  return sum;
}

यह बताता है कि डी-कंपाइलर 32-बिट सीमाओं पर संरेखित हैं, इसलिए कंपाइलर उस तरह के संरेखण के लिए विशिष्ट निर्देश उत्पन्न कर सकता है।


1
तो अगर वे झूठे हैं और NDEBUG सेट नहीं है तो वे क्या करते हैं? यदि यह <assert.h> से मुखर का संस्करण है, तो मानक के लिए आवश्यक है कि वह एक संदेश प्रिंट करे और गर्भपात करे। जाहिर है मानक यह नहीं कहते हैं कि उन्हें कथन की सच्चाई के आधार पर अनुकूलन करने की अनुमति नहीं है, लेकिन शिकायत करने के लिए उन्हें अभी भी गर्भपात करना होगा यदि यह गलत है।
स्टीव जेसप

1
वे मानक व्यवहार का पालन करते हैं
११

1

C ++ 11 N3337 मानक ड्राफ्ट

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf

19.3 जोर

1 शीर्ष लेख <कैसेट>, (तालिका 42) में वर्णित है, C ++ प्रोग्राम के अभिकथन के लिए एक मैक्रो प्रदान करता है और दावे की जांच को अक्षम करने के लिए एक तंत्र प्रदान करता है।

2 सामग्री मानक C लाइब्रेरी हेडर <assert.h> के समान है।

C99 N1256 मानक ड्राफ्ट

http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf

7.2 डायग्नोस्टिक्स <assert.h>

1 शीर्षलेख <assert.h>मुखर मैक्रो को परिभाषित करता है और एक अन्य मैक्रो को संदर्भित करता है, NDEBUGजो कि परिभाषित नहीं है <assert.h>। यदि NDEBUGस्रोत फ़ाइल में उस बिंदु पर एक स्थूल नाम के रूप में परिभाषित किया गया है जहां <assert.h> शामिल है, तो अभिकारक मैक्रो को बस के रूप में परिभाषित किया गया है

 #define assert(ignore) ((void)0)

प्रत्येक बार <assert.h>शामिल किए जाने वाले NDEBUG की वर्तमान स्थिति के अनुसार एस्टर मैक्रो को फिर से परिभाषित किया जाता है।

2. मुखर मैक्रो को मैक्रो के रूप में लागू किया जाएगा, वास्तविक कार्य के रूप में नहीं। यदि वास्तविक फ़ंक्शन तक पहुंचने के लिए मैक्रो परिभाषा को दबा दिया जाता है, तो व्यवहार अपरिभाषित होता है।

7.2.1 कार्यक्रम निदान

7.2.1.1 मुखर मैक्रो

सार

1।

#include <assert.h>
void assert(scalar expression);

विवरण

2 मुखर मैक्रो कार्यक्रमों में नैदानिक ​​परीक्षण करता है; यह एक शून्य अभिव्यक्ति के लिए फैलता है। जब इसे निष्पादित किया जाता है, अगर अभिव्यक्ति (जिसमें एक स्केलर प्रकार होगा) गलत है (जो कि 0 के बराबर है), मुखर मैक्रो उस विशेष कॉल के बारे में जानकारी लिखता है जो विफल रही (तर्क के पाठ सहित, नाम स्रोत फ़ाइल, स्रोत लाइन संख्या, और एन्क्लोज़िंग फ़ंक्शन का नाम - बाद वाले कार्यान्वयन-परिभाषित प्रारूप में मानक त्रुटि स्ट्रीम पर क्रमशः प्रीप्रोसेसिंग मैक्रोज़ __FILE__और ( __LINE__पहचानकर्ता के मान __func__) हैं। 165) यह तो गर्भपात कार्य कहता है।

रिटर्न

3 मुखर मैक्रो कोई मूल्य नहीं देता है।


1

सामान्य से अधिक एसेर () फ़ंक्शन का उपयोग करने के तीन मुख्य कारण हैं अगर और प्रिंटफ

  1. मुखर () फ़ंक्शन का उपयोग मुख्य रूप से डिबगिंग चरण में किया जाता है, यह लिखने के लिए थकाऊ है कि क्या एक प्रिंटफ स्टेटमेंट के साथ हर बार आप एक ऐसी स्थिति का परीक्षण करना चाहते हैं जो अंतिम कोड में भी अपना रास्ता नहीं बना सकती है।

  2. बड़े सॉफ्टवेयर परिनियोजन में, एस्टर बहुत काम आता है जहां आप कंपाइलर को () फंक्शन के लिए हेडर फाइल को लिंक करने से पहले परिभाषित NDEBUG मैक्रो का उपयोग करके एसेटर स्टेटमेंट को अनदेखा कर सकते हैं।

  3. जब आप कोई फ़ंक्शन या कुछ कोड डिज़ाइन कर रहे हों, तो assert () काम आता है और यह विचार करना चाहता है कि कोड क्या करेगा और काम नहीं करेगा और अंत में मूल रूप से मान्यताओं के साथ खेलने के लिए मूल्यांकन करने के लिए एक और शामिल करें।


0

यह एक फ़ंक्शन है जो प्रोग्राम निष्पादन को रोक देगा यदि मूल्य ने मूल्यांकन किया है तो वह गलत है। आमतौर पर इसे एक मैक्रो द्वारा घेर लिया जाता है ताकि इसे रिलीजिंग सेटिंग्स के साथ संकलित होने पर परिणामी बाइनरी में संकलित न किया जाए।

इसे आपके द्वारा की गई मान्यताओं के परीक्षण के लिए उपयोग करने के लिए डिज़ाइन किया गया है। उदाहरण के लिए:

void strcpy(char* dest, char* src){
    //pointers shouldn't be null
    assert(dest!=null);
    assert(src!=null);

    //copy string
    while(*dest++ = *src++);
}

आप जो आदर्श चाहते हैं, वह यह है कि आप अपने प्रोग्राम में कोई त्रुटि कर सकते हैं, जैसे कि किसी फ़ंक्शन को अमान्य तर्कों के साथ कॉल करना, और आप इससे पहले कि यह सेगफ़ॉल्ट (या अपेक्षा के अनुसार काम करने में विफल रहता है) पर जोर मारता है


क्यों न हम सिर्फ अगर और का उपयोग करें और कुछ लॉगिंग जानकारी जोड़ें?
असद खान

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

-5

इसके अलावा, आप यह जांचने के लिए उपयोग कर सकते हैं कि क्या गतिशील आवंटन सफल था।

कोड उदाहरण:

int ** p;
p = new int * [5];      // Dynamic array (size 5) of pointers to int
for (int i = 0; i < 5; ++i) {
    p[i] = new int[3]; // Each i(ptr) is now pointing to a dynamic
                       // array (size 3) of actual int values
}

assert (p);            // Check the dynamic allocation.

के समान:

if (p == NULL) {
    cout << "dynamic allocation failed" << endl;
    exit(1);
}

3
सं newआवंटन विफलता जब तक आपके द्वारा निर्दिष्ट पर एक अपवाद फेंकता है nothrow(जो आप यहाँ नहीं किया)। इसके अलावा, आपका स्वरूपण अजीब है और exitबुराई है।
को ऑर्बिट

हाँ आप सही है। मैं जोड़ना नहीं भूली। यह देखना पसंद करेंगे कि बाहर निकलने के बजाय आप कैसे उपयोग करेंगे
सादिकोव

1
@Sadikov कोई भी ऐसी त्रुटि स्थिति को कोड का उपयोग करके संभाल लेगा जो रिलीज़ मोड में निर्माण करने पर पूरी तरह से हटाया नहीं जाता है , जिससे आपके उपयोगकर्ता बिना सुरक्षा के और अपरिभाषित व्यवहार की दया पर छोड़ देते हैं यदि कोई पूर्व शर्त संतुष्ट नहीं है और इसके लिए धन्यवाद, कभी जाँच नहीं की और पकड़ा गयाassert()केवल डिबगिंग और उन चीज़ों पर मुहर लगाने के लिए है जो कभी भी, कभी भी, कभी भी नहीं होनी चाहिए - रिलीज बिल्ड बनने से बहुत पहले।
अंडरस्कोर_ड
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.