2010-03-24 12 views
8

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

#ifdef TESTING 
// code with lots of debugging info 
#else 
// clean code only 
#endif // TESTING` 

यह एक अच्छा तरीका है, या क्या कोई अन्य सरल और सुरुचिपूर्ण विधि है?

लेकिन इस तरह, मैं दो स्थानों पर एक ही कोड दोहरा रहा हूं और कोड में बाद में कुछ भी बदला जाना है, मुझे इसे दोनों जगहों पर करना है, जो समय लेने वाली और त्रुटि प्रवण है।

धन्यवाद।

मैं एमएस विजुअल स्टूडियो का उपयोग कर रहा हूं।

उत्तर

17

आप डीबग जानकारी मुद्रित करने के लिए मैक्रो का उपयोग कर सकते हैं और फिर रिलीज बिल्ड में, उस मैक्रो को खाली के रूप में परिभाषित कर सकते हैं।

जैसे

#ifdef _DEBUG 
#define DEBUG_PRINT(x) printf(x); 
#else 
#define DEBUG_PRINT(x) 
#endif 

इस विधि का प्रयोग करके आप की तरह

__LINE__ 
__FILE__ 
डिबग जानकारी के लिए

स्वचालित रूप से और अधिक जानकारी जोड़ सकते हैं।

+1

मैक्रोज़ खराब सी ++ शैली हैं। –

+0

शायद, लेकिन सवाल सी और सी ++ दोनों टैग किया गया था। –

+0

मैं एलेक्सी से सहमत नहीं हूं, मैं सी ++ और मैक्रोज़ के साथ सालों को किसी भी समस्या के साथ लिखता हूं। शायद खराब प्रोग्रामर के लिए खराब सी ++ शैली है, जो नहीं जानते कि वे क्या करते हैं, लेकिन केवल मैक्रोज़ के साथ मैं कुछ बहुत मुश्किल सोच सकता हूं। कई तरीकों का उपयोग करने की आजादी वह बुरा नहीं है :) – Aristos

2

उपयोग ऐसे ही एक परिभाषित पर हेडर

#ifdef TESTING 
#define DEBUG_INFOS(_X_) CallYourDebugFunction(_X_) 
#else 
#define DEBUG_INFOS(_X_) ((void)0) 
#endif 

और शामिल तो अपने कोड पर केवल इस का उपयोग

... 
DEBUG_INFOS("infos what ever"); 
RestOfWork(); 
... 

तुम भी इस्तेमाल करते हैं और ASSERT और ट्रेस मैक्रो के लिए खोज कर सकते हैं और डीबग व्यू सिसिनटरल्स से ट्रेस से आउटपुट वास्तविक समय पढ़ने के लिए, या एएसएसईआरटी के साथ समस्याओं को ट्रैक करने के लिए उपयोग करें। एसएसएसईटी और ट्रेक समान काम करते हैं, और आप उनसे विचार प्राप्त कर सकते हैं।

टिप्पणियां: मैं परीक्षण घोषणा का उपयोग करता हूं, क्योंकि मैं इसे प्रश्न पर देखता हूं।

5

लिखें एक बार

#ifdef _DEBUG 
const bool is_debig = true; 
#else 
const bool is_debig = false; 
#endif 

और फिर

template<bool debug> 
struct TemplateDebugHelper { 
    void PrintDebugInfo(const char*); 
    void CalcTime(...); 
    void OutputInfoToFile(...); 
    /// ..... 
}; 

// Empty inline specialization 
template<> 
struct TemplateDebugHelper<false> { 
    void PrintDebugInfo(const char*) {} // Empty body 
    void CalcTime(...) {} // Empty body 
    void OutputInfoToFile(...) {} // Empty body 
    /// ..... 
}; 

typedef TemplateDebugHelper<is_debug> DebugHelper; 

DebugHelper global_debug_helper; 

int main() 
{ 
    global_debug_helper.PrintDebugInfo("Info"); // Works only for is_debug=true 
} 
+0

अगर यह संकलित फाइलों पर किसी भी कोड को छोड़ दिया मैं तुम्हें पूछ सकता रिलीज़ मोड पर,? – Aristos

+0

, यह सेम खाली समारोह कैल। हालांकि, चूंकि कोड को कंपाइलर के लिए उपलब्ध होना है, मेरे अनुभव में भी ऑप्टिमाइज़ हो जाता है। –

+1

मुझे यह जवाब पसंद है, सिवाय इसके कि मेरा अनुभव यह है कि यदि किसी प्रोग्रामर को 'global_debug_helper.PrintDebugInfo' लिखना है तो वह परेशान नहीं होगा। मैं आमतौर पर छोटे कैप्स का उपयोग करता हूं ताकि उन्हें लिखना आसान हो, लेकिन स्पॉट करने में आसान: BUG.OUT ("जानकारी"); – swestrup

1

से आप अपनी आवश्यकतानुसार को boost::log सेटिंग गंभीरता स्तर की तरह कुछ इस्तेमाल कर सकते हैं।

void init() 
{ 
    logging::core::get()->set_filter 
    (
     flt::attr<logging::trivial::severity_level>("Severity") >= logging::trivial::info 
    ); 
} 

int main(int, char*[]) 
{ 
    init(); 

    BOOST_LOG_TRIVIAL(trace) << "A trace severity message"; 
    BOOST_LOG_TRIVIAL(debug) << "A debug severity message"; 
    BOOST_LOG_TRIVIAL(info) << "An informational severity message"; 
    BOOST_LOG_TRIVIAL(warning) << "A warning severity message"; 
    BOOST_LOG_TRIVIAL(error) << "An error severity message"; 
    BOOST_LOG_TRIVIAL(fatal) << "A fatal severity message"; 
} 

मुझे लगता है कि pantheios भी कुछ इसी तरह की है।

2

अपना खुद का लॉगिंग रोल करने के बजाय Log4Cxx का उपयोग करें। Log4Cxx पैकेज अत्यधिक विन्यास योग्य है, महत्व/गंभीरता के आधार पर लॉगिंग के विभिन्न स्तरों का समर्थन करता है, और आउटपुट के कई रूपों का समर्थन करता है।

इसके अतिरिक्त, जब तक कि यह बहुत ही महत्वपूर्ण कोड नहीं है, जिसे सुपर अनुकूलित किया जाना चाहिए, मैं आपके कोड में लॉगिंग स्टेटमेंट (आप लॉग 4Cxx का उपयोग करने) मानने की सलाह दूंगा, लेकिन लॉगिंग स्तर को बस बंद कर दूंगा।इस तरह, लॉगिंग गतिशील रूप से सक्षम किया जा सकता है, जो अविश्वसनीय रूप से सहायक हो सकता है यदि आपके उपयोगकर्ताओं में से एक को हार्ड-टू-प्रतिकृति बग का अनुभव होता है ... केवल उन्हें उच्च लॉगिंग स्तर को कॉन्फ़िगर करने के तरीके पर निर्देशित करें। यदि आप निष्पादन योग्य से लॉगिंग को पूरी तरह से बढ़ाते हैं, तो फ़ील्ड में उस मूल्यवान डीबगिंग आउटपुट को प्राप्त करने का कोई तरीका नहीं है।

+1

यह। मेरी टीम की प्रोजेक्ट में, हमने ट्रैक संदेशों में संकलन पाया, प्रदर्शन पर एक उल्लेखनीय प्रभाव नहीं पड़ा जब तक कि हम वास्तव में ट्रेसिंग सक्षम नहीं करते हैं, और log4xxx फ्रेमवर्क की सुंदरता यह है कि आप कुछ लॉग स्रोतों के लिए ऐसा कर सकते हैं लेकिन दूसरों के आधार पर नहीं आप जो लक्ष्य करने की कोशिश कर रहे हैं उस पर। हमारे कोड में कुछ जगहें हैं जहां ट्रेस लॉग कॉल के तर्क गणना करने के लिए महंगे हैं; इनके लिए, हम केवल लॉगर :: isEnabledFor (LogLevelTrace) को यह पता लगाने के लिए कहते हैं कि किसी दिए गए लॉगर के लिए ट्रेसिंग कब होती है; यदि ऐसा है तो हम महंगी तर्क बनाते हैं और ट्रेस संदेश लॉग करते हैं, अन्यथा हम इसे अकेला छोड़ देते हैं। – anelson

+0

@anelson, आपने LOG4CXX_TRACE (LOGGER, MSG) का उपयोग क्यों नहीं किया? मेरा मानना ​​है कि मैक्रो पहले से ही आपके लिए यह जांच करता है। –

0

मैं सी में एम्बेडेड प्रणाली के लिए लिख रहा हूँ मेरे कार्यक्रमों में मैं निम्नलिखित मैक्रो का उपयोग कर रहा हूँ:

 
#define _L log_stamp(__FILE__, __LINE__) 

#define _LS(a) log_string(a) 

#define _LI(a) log_long(a) 

#define _LA(a,l) log_array(a,l) 

#define _LH(a) log_hex(a) 

#define _LC(a) log_char(a) 

#define ASSERT(con) log_assert(__FILE__, __LINE__, con) 

जब मैं रिलीज़ संस्करण बना रही हूँ, मैं बस #define डीबग निर्देश बंद कर और सभी मैक्रोज़ खाली हो जाते हैं। ध्यान दें कि यह रिलीज संस्करण में किसी भी CPU चक्र और स्मृति का उपभोग नहीं करता है। मैक्रोज़ लॉग जानकारी को सहेजने का एकमात्र तरीका है: जहां लॉगिंग (फ़ाइल और लाइन नंबर) किया गया था।

मैं इस जानकारी की जरूरत है मैं का उपयोग करें: _L;_LS("this is a log message number ");_LI(5);

अन्यथा बिना _L निर्देश।

0

वहाँ एक आसान तरीका है, जो सबसे compilers के साथ काम करता है:

#ifdef TESTING 
    #define DPRINTF(args)  printf args 
#else 
    #define DPRINTF(args)  ((void)0) 
#endif 

इसके बाद, स्रोत कोड में आप इसे के रूप में उपयोग करना चाहिए:

DPRINTF(("Debug: value a = %d, value b = %d\n", a, b)); 

दोष यह आप का उपयोग करने के लिए है कि है डबल ब्रांड्स, लेकिन पुराने सी और सी ++ मानक वैरिएडिक मैक्रो समर्थित नहीं हैं (केवल एक कंपाइलर एक्सटेंशन के रूप में)।

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