2013-01-22 136 views
15

我讀到有關__noop和MSDN的例子是爲什麼以及何時使用__noop?

#if DEBUG 
    #define PRINT printf_s 
#else 
    #define PRINT __noop 
#endif 

int main() { 
    PRINT("\nhello\n"); 
} 

,我沒有看到過增益僅僅有一個空的宏:

#define PRINT 

生成的代碼是一樣的。什麼是使用__noop的有效示例,它實際上有用?

+0

我想有些情況下,「無聲明」會改變事情的工作方式。不完全確定我現在可以想到一個。 –

+2

順便說一句,他們的例子有點狡猾,因爲它導致在調試和發佈模式下具有不同類型的表達式。但它不像調試模式中的類型那麼狡猾,無論「PRINT」的「參數」是什麼!變量宏允許定義更好的定義'#define PRINT(...)((void)printf_s(__ VA_ARGS __))'和'#define PRINT(...)((void)0)',這也會阻止你試圖用'&PRINT'來取一個函數指針。 –

回答

15

一個函數應該被忽略的__noop內在指定和參數列表解析但對於參數不會產生代碼。它旨在用於採用可變數量參數的全局調試功能。

在你的情況下,參數是一個明顯的副作用自由表達式,可以很容易地進行優化,所以沒關係。

但是,如果參數表達式有副作用或如此複雜以至於編譯器無法證明它正常終止並且沒有副作用,那麼使用__noop可以防止對該表達式進行潛在的昂貴評估。

第二個好處是,它的行爲就像一個函數調用,語法上具有可變數目的參數。因此,將其替換爲函數調用不會影響程序的解析。有了其他替代品(如空字符串),在某些情況下可能會出現問題。

+0

是的,我認爲就是這樣。 :) –

12
#define PRINT 
extern int some_complicated_calculation(); 
PRINT("%d\n", some_complicated_calculation()); 

即使您不想要結果,也會調用該函數。

使用__noop,函數將不會被調用。你可以(假定編譯器支持可變宏)定義PRINT來忽略參數;你可以(假設編譯器支持可變宏)定義PRINT來忽略參數;但之後它們將不會被解析,並且如果您更改其周圍的代碼而不編譯定義PRINT做某事的變體,它們可能會失效。使用__noop,參數仍然被解析,所以更有可能保持有效。

相關問題