2012-12-16 64 views
1

ON_BLOCK_EXIT是由ScopeGuardimplementation提供的實用宏。它定義了一個局部對象,因爲它的用戶提供的析構函數在超出範圍時被執行。它被定義爲:如何禁止來自ON_BLOCK_EXIT(ScopeGuard的一部分)的警告

#define CONCATENATE_DIRECT(s1, s2) s1##s2 
#define CONCATENATE(s1, s2) CONCATENATE_DIRECT(s1, s2) 
#define ANONYMOUS_VARIABLE(str) CONCATENATE(str, __LINE__) 

#define ON_BLOCK_EXIT ScopeGuard ANONYMOUS_VARIABLE(scopeGuard) = MakeGuard 

,並且可以像這樣使用:

void foo() { 
    HANDLE hFile = CreateFile(...); 
    ON_BLOCK_EXIT(CloseHandle, hFile); 
    // more... 
    // ... code... 
    // ... following 
} // warning C4189 

當使用Visual Studio 2010編譯的代碼上面生成以下warning C4189: 'scopeGuard3' : local variable is initialized but not referenced

#pragma warning(suppress : 4189)可用於暫時禁用警告。但是,這有兩個問題:1.)它不能放在導致警告的語句旁邊,而是必須放在結束範圍的行的上方。 2.)作爲一個必然結果,它會掩蓋掉全部由當前範圍產生的警告4189。

使用Visual Studio 2010有沒有什麼辦法可以禁止由ON_BLOCK_EXIT(最好不用改變呼叫站點,類似於GCC的__attribute__((unused)))創建的那些對象導致的特定警告?

+4

而不是正確的RAII包裝會有這些問題。而且這也是可重用的。每次調用CreateFile時都不需要記住添加樣板文件ON_BLOCK_EXIT。也許有一天我會明白爲什麼人們爲了得到更少的利益而經歷額外的麻煩。 –

+0

我會寫一個'MakeGuard'的包裝器,它包含一個可以傳遞'ANONYMOUS_VARIABLE(scopeGuard)'的僞參數。 –

+0

@Johannes Schaub:謝謝你的正確方向。雖然我最終實施的解決方案不是起點。 – IInspectable

回答

1

我終於去了作品的Visual Studio 2005或更高版本的解決方案:

#define ON_BLOCK_EXIT(...) ScopeGuard ANONYMOUS_VARIABLE(scopeGuard) = \ 
           MakeGuard(__VA_ARGS__); \ 
           (void)ANONYMOUS_VARIABLE(scopeGuard) 

原來的宏沒有擴展到完整的表達,所以沒有辦法附加任何儀器來指示編譯器不發出警告。使用可變宏提供了該選項。