回答
這樣就可以將整個參數列表傳遞給宏,並讓它傳遞給一個帶有可變數量參數的函數。
我敢打賭任何宏觀的定義是:
#if DEBUG /* or something like it */
#define KdPrint(args) (printf args)
#else
#define KdPrint(args) /* empty */
#endif
或相近的工作就像printf的一些其他功能。
如果它被定義爲printf(args),那麼您只能傳遞單個字符串參數,因爲宏的參數不能包含不在嵌套圓括號內的逗號。
它導致在parens內的所有東西都被視爲宏的單個參數。在顯示的例子,它可以允許可變參數類型的參數:
KdPrint(("My info is %s\n", "my name"));
至於以及
KdPrint(("fn %s ln %s\n", "my", "name"));
如果有問題的宏並沒有使用括號寫得很好,可能是因爲運營商是必要的優先。就拿這個宏例如:
#define MY_MACRO(a) a * 11
好吧,如果你這樣做:
int b = MY_MACRO(1 + 2);
b
,的而不是33像它應該,實際上與int b = 1 + 2 * 11
這是23而不是33來代替。如果你的宏不是這樣寫的,儘管(沒有圍繞a
的括號),那就沒有必要了。
雖然對宏觀陷阱有深入的瞭解,但如果這確實是問題,那麼KdPrint會在宏本身中放置括號。它更可能是a)它需要將所有參數傳遞給一個接受可變數量參數的函數,或者b)它試圖與不支持__VA_ARGS__的預處理器兼容,這意味着您必須傳遞所有參數作爲一個單一的宏參數,直到它們達到功能級別。 – 2013-08-08 21:47:40
對於您的具體示例,我無法告訴您,因爲我不知道XdPrint是什麼。
但在更一般的情況下,這是因爲我喜歡搜索和替換的宏。假設你有:
#define MULT(a,b) (a*b)
如果你打電話MULT(1+1, 2+2)
,它會成爲1+1*2+2
,並導致作爲5
而不是8
正如你期望的那樣。做MULT((1+1), (2+2))
會給你預期的結果。這就是爲什麼你需要加倍括號。
如果this是您所說的KdPrint()
,那麼這是因爲您可以使用帶格式參數的KdPrint()
宏,而且它不是可變長度的宏。
例如,你可以這樣做:
KdPrint(("The answer is %d\n", 42));
等。
- 1. 爲什麼括號需要
- 2. 爲什麼在這裏需要括號?
- 3. 爲什麼我們需要圍繞宏塊的括號?
- 4. 爲什麼我需要在RegEx中使用雙曲括號?
- 5. 爲什麼在這個宏定義中需要@符號?
- 6. 爲什麼「typeof」不需要括號?
- 7. 爲什麼在Haskell中需要花括號爲'neg square 4.2'?
- 8. 爲什麼在這個lambda函數週圍需要括號?
- 9. 爲什麼要在arity-1方法調用中使用括號括號?
- 10. 爲什麼在元組中需要括號?
- 11. 節點需要有兩個括號
- 12. 爲什麼我的serialVersionUID後需要一個大括號?
- 13. 爲什麼打印一個整數的__repr__需要括號?
- 14. 爲什麼我需要在下面的perl one liner中使用大括號?
- 15. 爲什麼C#在表達式中使用可空字符時需要括號?
- 16. 爲什麼在寫入SAS宏時,proc不需要%符號
- 17. 在javascript數組中使用兩個括號是什麼意思
- 18. JavaScript即時函數調用 - 爲什麼函數需要括號?
- 19. json文本需要用括號包裝。爲什麼?
- 20. 爲什麼CoffeeScript在下列情況下需要括號?
- 21. 爲什麼紅寶石在這裏需要括號?
- 22. 爲什麼xcopy需要多個引號?
- 23. 爲什麼需要嵌套宏?
- 24. 爲什麼在emacs lisp中`let`後面有兩個括號?
- 25. 爲什麼(以及何時)需要在sizeof之後使用圓括號?
- 26. 爲什麼Comparator.compare需要兩個參數?
- 27. 如何避免在此預處理器宏中需要括號?
- 28. 爲什麼在AT&T裝配中需要使用'$'符號?
- 29. 爲什麼在Clojure中使用conj的列表需要撇號?
- 30. 爲什麼pip需要感嘆號才能在iPython中使用?
你可能是對的!但是我認爲編寫這個宏的人做得不好。他應該圍繞'args'放置括號。 – 2011-04-28 02:34:01
不,重點是逗號可能不止一個,所以它在宏外面加括號。 – Random832 2011-04-28 02:37:42
明白了,謝謝 – 2011-04-28 02:44:00