回答
这样就可以将整个参数列表传递给宏,并让它传递给一个带有可变数量参数的函数。
我敢打赌任何宏观的定义是:
#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