2010-09-28 137 views
6

我有以下宏:C預處理與if語句

#define IF_TRACE_ENABLED(level) if (IsTraceEnabled(level)) 

用戶代碼應該如下:

IF_TRACE_ENABLED(LEVEL1) 
{ 
    ... some very smart code 
} 

這裏花括號強調 - 我要防止「如果」從宏 「吃」 其他代碼:

if (...) 
    IF_TRACE_ENABLED(LEVEL1) 
     printf(....); 
else 
    bla bla bla 

在這個例子中IF_TRACE_ENABLED 「吃」 else塊。

有沒有辦法強制用戶代碼不編譯沒有卷閘或有其他來定義宏來實現安全?

+2

我沒有看到這個宏給你的裸if語句。 – JeremyP 2010-09-28 10:29:03

+2

忘掉這個例子。你可能會遇到一個複雜的情況,那就是你不想每次都重複一遍。 – 2010-09-28 11:08:37

+0

@JeremyP:在這個簡單的例子中,沒有太多實用的宏,但是正如Nathan指出的那樣,在調試宏中可能會有更多的複雜性和/或基於構建配置的宏有多種變化例如,總是評估爲「false」的版本版本,以便跟蹤字符串從可執行文件中除去)。 – 2010-09-28 14:37:09

回答

11

這並不強制宏的用戶使用大括號,但它會防止不小心被吃掉的else條款:

#define IF_TRACE_ENABLED(level) if (!IsTraceEnabled(level)) {} else 

一個側面說明:在printf()左右括號中的第二個例子該問題不會解決問題 - 與bla bla bla關聯的else仍將綁定到宏中的if語句。

+1

嘗試並未能想出一個辦法,這可能會適得其反。 +1 – 2010-09-28 08:46:38

+0

「if」塊的內容在哪裏通過?在else塊中的 – dimba 2010-09-28 09:42:58

+1

;很好的答案! – 2010-09-28 10:08:46

0

這應該工作,但你必須在通過該if塊的內容作爲參數傳遞給宏還有:

#define IF_TRACE_ENABLED(level,content) { if (IsTraceEnabled(level)) {content} } 
+0

這不是必需的printf(...)。這可以是隻有在宏條件爲真時才應該評估的任何代碼。 – dimba 2010-09-28 08:02:37

+0

您應該在內容周圍添加一個塊。 – 2010-09-28 08:03:41

+0

@Ronny - 這是我想要強制執行的用戶,所以如果他忘記這樣做,彙編將失敗 – dimba 2010-09-28 08:19:00

2

你可以試試這個:

#define IF_TRACE_ENABLED(level) do { if(IsTraceEnabled(level)) { 
#define END_TRACE_ENABLED } } while(0); 

我不要以爲只有宏的開頭才能「強制」好語法。你將需要使用兩個。

編輯

我已經添加了一對額外的括號的宏內部,以避免所有歧義。

在迴應的意見,這個宏的意思是這樣使用:

IF_TRACE_ENABLED(LEVEL1) 
    printf("Trace\n"); 
END_TRACE_ENABLED 

不作爲的聲明。爲了記錄,我認爲這是對預處理器的濫用,沒有人應該這樣做。如果有必要,將它寫出來用#ifdef DEBUG括起來有什麼問題。

+0

我在解決方案中唯一不喜歡的是stat和stop宏之間的縮進 - 編輯器不會縮進它。 – dimba 2010-09-28 08:05:02

+1

是不是可以簡單地使用大括號,而不做&while? – 2010-09-28 08:07:23

+0

@ptmato - @crypto說有什麼。 do/while用於在宏前面看起來像普通函數,因爲他強制使用「;」到底。所以「;」在宏觀的結尾是多餘的。 任何我們不會「;」的方式因爲這個宏看起來不像函數調用 – dimba 2010-09-28 08:22:02