2009-11-18 17 views
2

這是我一直在想的一個小問題,現在我還沒有找到解決方案。範圍守衛的每個文件啓用

所以,首先,我必須說我在調試時使用用途此功能後衛:

class FuncGuard 
{ 
public: 
    FuncGuard(const TCHAR* funcsig, const TCHAR* funcname, const TCHAR* file, int line); 
    ~FuncGuard(); 
// ... 
}; 

#ifdef _DEBUG 
    #define func_guard() FuncGuard __func_guard__(TEXT(__FUNCSIG__), TEXT(__FUNCTION__), TEXT(__FILE__), __LINE__) 
#else 
    #define func_guard() void(0) 
#endif 

警衛的目的是幫助通過打印一些信息到調試跟蹤的代碼需要在運行時路徑安慰。它的目的是使用,如:

void TestGuardFuncWithCommentOne() 
{ 
    func_guard(); 
} 

void TestGuardFuncWithCommentTwo() 
{ 
    func_guard(); 
    // ... 
    TestGuardFuncWithCommentOne(); 
} 

,它給這個結果:現在

 
..\tests\testDebug.cpp(121): 
Entering[ void __cdecl TestGuardFuncWithCommentTwo(void) ] 
    ..\tests\testDebug.cpp(114): 
    Entering[ void __cdecl TestGuardFuncWithCommentOne(void) ] 
    Leaving[ TestGuardFuncWithCommentOne ] 
Leaving[ TestGuardFuncWithCommentTwo ] 

,一兩件事,我很快意識到的是,它是一個痛苦的添加和刪除衛士來自函數調用。將它們永久留在那裏也是不可想象的,因爲它沒有很好的理由會耗盡CPU週期,並且可能很快導致應用程序崩潰。另外,即使在調試中對應用程序的性能沒有影響,調試控制檯中也會很快出現大量信息,使得此調試工具的使用毫無用處。

因此,我認爲在每個文件的基礎上啓用和禁用它們可能是一個好主意。

這個想法是讓所有默認禁用功能守衛,但他們可以自動地在整個文件只需在文件的頂部添加一行如

EnableFuncGuards(); 

啓用。

我想過很多這方面的解決方案。由於我的問題已經足夠長了,所以我不會詳細討論這些細節,但是我只想說我已經嘗試了一些涉及宏都失敗的技巧,一個涉及顯式實現模板,但目前爲止,沒有一個可以讓我得到我期待的實際結果。

要注意的另一個限制因素:通過預編譯頭包含當前實現函數保護機制的頭文件。我知道這會讓事情變得複雜,但如果有人能夠想出一個可以在這種情況下工作的解決方案,那就太棒了。如果沒有,那麼我當然可以從預編譯的頭文件中提取該頭文件。

非常感謝!

回答

2

將一個bool添加到FuncGuard控制它是否應該顯示任何內容。

#ifdef NDEBUG 
    #define SCOPE_TRACE(CAT) 
#else 
    extern bool const func_guard_alloc; 
    extern bool const func_guard_other; 
    #define SCOPE_TRACE(CAT) \ 
    NppDebug::FuncGuard npp_func_guard_##__LINE__(\ 
     TEXT(__FUNCSIG__), TEXT(__FUNCTION__), TEXT(__FILE__), \ 
     __LINE__, func_guard_##CAT) 
#endif 

實現文件:

void example_alloc() { 
    SCOPE_TRACE(alloc); 
} 
void other_example() { 
    SCOPE_TRACE(other); 
} 

此:

  • 使用特定類別(包括每個如果你喜歡的文件之一)
  • 允許多種用途於一體的功能,一個按類別或邏輯範圍(通過在變量名中包括行號)
  • 編譯爛掉在NDEBUG構建(NDEBUG是標準的我 - 不 - 調試宏)

您需要包含您的類別的bool定義單個項目範圍的文件,更改此「設置」文件不需要重新編譯任何其他程序(只是鏈接),所以你可以get back to work。 (這意味着它也可以在預編譯頭文件的情況下正常工作。)

進一步的改進涉及告訴FuncGuard關於該類別,因此它甚至可以登錄到多個位置。玩的開心!

+0

雖然很有趣,但這個解決方案仍然存在一個主要缺陷,即每個新類別都需要修改兩個文件。 但我想這是迄今爲止我見過的最好的實現。 謝謝! – joce 2009-11-18 04:05:47

+0

自己實現後,我意識到對於「每個文件」啓用,您的解決方案不需要修改2個文件!布爾值不需要在文件範圍之外公開!甜! – joce 2009-11-18 04:51:51

1

你可以做類似的地方有一些宏觀定義或沒有變化(assert()的情況下NDEBUG)的assert()的定義assert()宏觀的東西。

像下面這樣(未經):

#undef func_guard 
#ifdef USE_FUNC_GUARD 
#define func_guard() NppDebug::FuncGuard __npp_func_guard__(TEXT(__FUNCSIG__), TEXT(__FUNCTION__), TEXT(__FILE__), __LINE__) 
#else 
#define func_guard() void(0) 
#endif 

有一點要記住的是,包括文件,這是否不能有包括警衛宏(至少不是解決此部分)。

然後你可以使用它像這樣得到追查即使在一個編譯單元控制:

#define USE_FUNC_GUARD 
#include "funcguard.h" 

// stuff you want traced 

#undef USE_FUNC_GUARD 
#include "funcguard.h" 

// and stuff you don't want traced 

當然,這不符合預編譯頭髮揮100%的好,但我認爲,後續包括預編譯後的東西仍然可以正常工作。即使如此,這可能是那種不應該在預編譯頭文件集中的東西。

+0

我個人發現「功能」重新包括難以使用和很少需要。 – 2009-11-18 03:12:35