2013-08-13 10 views
30

मुझे पता है कि static_assert संकलन समय पर दावा करता है, और assert - रन समय पर, लेकिन अभ्यास में अंतर क्या है? जहां तक ​​मैं समझता हूँ, नीचे गहरी वे कोड के टुकड़े,जोर और static_assert के बीच क्या अंतर है?

if (condition == false) exit(); 
  • की तरह किसी ने मुझे जहां केवलstatic_assert काम करेंगे का एक उदाहरण है, या केवलassert दे सकते हैं?
  • क्या वे कुछ भी सरल करते हैं if कथन नहीं कर सकता है?
  • क्या इसका उपयोग करना बुरा व्यवहार है?
+0

'static_assert' एक घोषणा है, जो मूल भाषा में बनाई गई है। यह किसी भी चीज़ में विस्तार नहीं करता है क्योंकि यदि यह सफल नहीं होता है, तो संकलन बंद हो जाता है। – jrok

+4

@KerrekSB मैंने ** तीन ** स्पष्ट प्रश्न पूछे हैं, कृपया – Oleksiy

+1

धारणा बनाने से पहले उन्हें पढ़ने के लिए समय दें, आप यह निर्दिष्ट करने के लिए जोर देते हैं कि आपके प्रोग्रामिंग तर्क में कोई त्रुटि है और इसे कोड में ठीक किया जाना चाहिए। कोड में विभिन्न लॉजिकल पथों के बीच शाखा में 'if' का उपयोग किया जाता है। यह एक बड़ा अंतर – Default

उत्तर

35

आप तीन प्रश्न पूछते हैं, इसलिए मैं उनमें से प्रत्येक का जवाब देने की कोशिश करूंगा।

  • कोई मुझे केवलstatic_assert काम करेंगे जहां, या केवलassert का एक उदाहरण दे सकते हैं?

static_assert संकलन समय पर आपके कोड में तर्क परीक्षण के लिए अच्छा है। assert रन-टाइम के दौरान किसी मामले की जांच करने के लिए अच्छा है जिसे आप हमेशा एक परिणाम होना चाहिए, लेकिन शायद किसी भी तरह से अप्रत्याशित परिस्थितियों में अप्रत्याशित परिणाम उत्पन्न कर सकता है।उदाहरण के लिए, आपको यह निर्धारित करने के लिए केवल assert का उपयोग करना चाहिए कि किसी विधि में पास किया गया पॉइंटर null है जब ऐसा लगता है कि ऐसा कभी नहीं होना चाहिए। static_assert इसे पकड़ नहीं पाएगा।

  • क्या वे कुछ भी सरल करते हैं if कथन नहीं कर सकता है? तो आप एक if, एक उपयुक्त त्रुटि संदेश इस्तेमाल कर सकते हैं, और उसके बाद प्रोग्राम निष्पादन को रोकने के लिए एक समान प्रभाव प्राप्त करने के

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

  • यह बुरा व्यवहार उन्हें इस्तेमाल करने के है?

बिलकुल नहीं!

+0

अच्छा जवाब, हालांकि, यह कहते हुए कि जोर (रन-टाइम संस्करण) केवल डीबग बिल्ड में काम करता है और रिलीज में एक नोप शायद एक अच्छा विचार है। रिहाई के निर्माण के लिए ऑप्टिमाइज़िंग की कुछ संभावित रूप से अनावश्यक त्रुटि जांच को हटाने के लिए, व्यापक डीबग परीक्षण के साथ, यदि एक कथन पर अच्छा हो सकता है। इसके अलावा एक चेतावनी के संश्लेषण में राज्य बदलते तर्क को न डालने पर विचार करने के लिए एक चेतावनी, क्योंकि परिणामी तर्क रिलीज निर्माण में मौजूद नहीं होगा ... इस प्रकार उदाहरण के लिए (x ++ <12) जोर से, x ++ रिलीज बिल्ड में मौजूद नहीं है, केवल डीबग में – Kit10

1

static_assert एक संकलक निर्देश है। यह आपको संकलन समय पर प्रकार की जानकारी की जांच करने की अनुमति देता है। यह एक संकलन विफलता का कारण बन जाएगा और एक त्रुटि संदेश उत्पन्न करेगा कि अधिकांश आईडीई में पकड़ा और आईडीई की त्रुटि विंडो में प्रदर्शित किया जाएगा।

static_assert(sizeof(int) == 4,"int should be 4 bytes"); 

assert क्रम के लिए, आप एक वेरिएबल का मान की जाँच कर सकते है। अगर दावा विफल रहता है तो दावा ट्रिगर होगा। यह एक त्रुटि संदेश बॉक्स (कार्यान्वयन पर जोर निर्भर)

assert(("mypointer should never be null!", mypointer != nullptr)); 
+1

कंपाइलर "निर्देश" संभवतः काफी शब्दावली नहीं है जिसका उपयोग मैं करता हूं ... –

+0

' 'में परिभाषित जोर मैक्रो को दो तर्क नहीं लेते हैं – Joe

+0

@joe, ठीक है, वाक्यविन्यास को ठीक किया गया है। –

11

static_assertसंकलन निर्दिष्ट संदेश के साथ विफल बनाने का मतलब है कुछ ऑपरेटिंग सिस्टम में रनटाइम पर दिखाई देगा कारण होगा, जबकि परंपरागत assert खत्म करने के लिए है आपके कार्यक्रम का निष्पादन

6

ठीक है, मैं काट देंगे:

  • केवल static_assert काम करता है अगर आप संकलन चाहते असफल रोकने के लिए अगर एक स्थिर हालत का उल्लंघन किया जाता है: assert(argc == 1);

  • : static_assert(sizeof(void*) != 3, "Wrong machine word size"); * यह केवल गतिशील दावे गतिशील स्थिति पकड़ कर सकते हैं

    सरल if बयान वैध और संकलित होना चाहिए; स्थैतिक दावे संकलन विफलताओं का कारण बनता है।

  • सं

*) एक व्यावहारिक उदाहरण ऐसे int x; std::move<int&&>(x) के रूप में सामान्य टेम्प्लेट निर्माण, का दुरुपयोग रोकने के हो सकता है।

3

क्या इसका उपयोग करना बुरा व्यवहार है?

यदि दुर्व्यवहार किया गया है, हाँ, विशेष रूप से assert

एक दुर्व्यवहार सक्रिय होने के लिए उन assert कथनों के आधार पर है। आपको कुछ भी करने के लिए assert पर कभी भी निर्भर नहीं होना चाहिए क्योंकि कोड को NDEBUG परिभाषित किया जा सकता है और फिर assert कुछ भी नहीं करता है। उत्पादन कोड को कई बार NDEBUG के साथ संकलित किया गया है ताकि यह सुनिश्चित किया जा सके कि assert कथन गायब हो जाएं।

जब तक कि आप एक-ऑफ प्रोग्राम नहीं लिख रहे हैं जो एक या दो दिन से अधिक समय तक नहीं जी रहेगा, तो आपको उपयोगकर्ता इनपुट को सत्यापित करने के लिए उपयोग नहीं करना चाहिए। उपयोगकर्ता इस बात पर परवाह नहीं करते कि कोड कहां विफल हुआ, और मुद्रित संदेश कई उपयोगकर्ताओं को एक विदेशी भाषा की तरह दिखता है। यह उपयोगकर्ता को त्रुटि को ठीक करने का तरीका नहीं बताता है। यह डिजाइन द्वारा भी बहुत क्षमाशील है। उपयोगकर्ता इनपुट त्रुटि के जवाब में जारी किया गया संदेश एक संदेश होना चाहिए जो उपयोगकर्ता को समस्या को ठीक करने का तरीका बताता है। संदेश के बाद सबसे अच्छी कार्रवाई उपयोगकर्ता को त्रुटि को ठीक करने का तरीका प्रदान करना है। यदि ऐसा नहीं किया जा सकता है, और यदि कार्यक्रम को समाप्त करने का एकमात्र व्यवहार्य प्रतिक्रिया है, तो कार्यक्रम को साफ-सफाई समाप्त करनी चाहिए। डिज़ाइन द्वारा, assert का परिणाम साफ शटडाउन नहीं होता है। यह exit() की बजाय abort() पर कॉल करता है।

कई मशीनों पर abort() का एक परिणाम कोर डंप का उत्पादन करना है। एक कोर डंप प्रोग्रामर के लिए एक महान त्रुटि संदेश है। कोर डंप के साथ, एक प्रोग्रामर डीबगर का उपयोग करके देख सकता है कि क्या बहुत बढ़िया हुआ है। abort() का नकारात्मक पक्ष यह है कि चीजें साफ़ नहीं की जाती हैं। निरस्त "स्वचालित या स्थैतिक भंडारण अवधि की वस्तुओं के लिए विनाशकों को निष्पादित किए बिना कार्यक्रम को समाप्त कर देता है और बिना कार्यों को atexit() पर कॉल किए बिना कॉल करता है।"

नीचे पंक्ति: प्रोग्रामिंग त्रुटियों के परीक्षण के लिए assert का उपयोग करने के लिए यह ठीक है (और अच्छा), लेकिन केवल एक गैर-उत्पादन सेटिंग में। उपयोगकर्ता त्रुटियों के परीक्षण के लिए कुछ और उपयोग करें।

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