簡體   English   中英

如何分離調試和釋放模式代碼

[英]how to separate debug and release mode code

在調試模式或我正在進行測試時,我需要打印大量的各種信息,所以我使用這種方法:

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

這是一個好方法,還是有其他簡單而優雅的方法?

但是這樣,我在兩個地方重復相同的代碼,如果稍后要在代碼中進行更改,我必須在兩個地方都這樣做,這既費時又容易出錯。

謝謝。

我正在使用MS Visual Studio。

您可以使用宏來打印調試信息,然后在發布版本中將該宏定義為空。

例如,

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

使用此方法,您還可以添加更多信息

__LINE__ 
__FILE__

自動調試信息。

寫一次

#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
}

在包含標題上使用類似的定義

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

然后在你的代碼上只使用它

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

您還可以使用和搜索ASSERTTRACE宏,並使用sysinternals中的DebugView從跟蹤中讀取輸出實時,或跟蹤ASSERT的問題。 ASSERT和TRACE做類似的工作,你可以從他們那里得到想法。

評論:我使用TESTING聲明,因為我在問題上看到了。

使用Log4Cxx ,而不是滾動自己的日志記錄。 Log4Cxx包是高度可配置的,支持基於重要性/嚴重性的不同級別的日志記錄,並支持多種形式的輸出。

此外,除非必須進行超級優化的非常關鍵的代碼,否則我建議在代碼中保留日志記錄語句(假設您使用Log4Cxx),但只需調低日志記錄級別。 這樣,可以動態啟用日志記錄,如果您的某個用戶遇到難以復制的錯誤,這可能會非常有用......只需指導他們如何配置更高的日志記錄級別。 如果您完全忽略了可執行文件的日志記錄,那么就無法在該字段中獲得有價值的調試輸出。

您可以使用boost :: log setting severity level之類的東西。

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也有類似的東西。

有一種簡單的方法,適用於大多數編譯器:

#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));

缺點是必須使用雙括號,但在舊的C和C ++標准中,不支持變量宏(僅作為編譯器擴展)。

我正在用C語言編寫嵌入式系統。在我的程序中,我正在使用以下宏:

#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 DEBUG指令,所有宏都變空。 請注意,它不會消耗發行版中的任何CPU周期和內存。 宏是保存日志信息的唯一方法:記錄完成的位置(文件和行號)。

如果我需要這些信息,我使用: _L;_LS("this is a log message number ");_LI(5);

否則沒有_L指令。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM