看到这个问题让我想知道为什么这个方法(玩具示例):
#define foo(x) bar[x] = 0
永远比这个功能更受欢迎:
void foo(unsigned x){ bar[x] = 0; }
在上面提到的问题之前,我之前只看过一次,在PolarSSL库中,我认为它是某种优化,并试图不要过多考虑它.
我假设使用预处理器宏将'call'替换为它所存在的'(not-)函数体'; 然而,void编译器可能会或可能不会优化该函数,因此可能导致大量分支用于小型和简单的操作或两次.
还有其他好处吗?
何时首选宏方法,何时更好地信任编译器?
首先,我希望您的宏实际上是:
#define foo(x) do { bar[x] = 0; } while (0)
用于适当的分号吞咽。
支持宏的一件事是因为您认为编译器的优化器不够好。你可能是错的。但是,如果您实际上仔细地查看了输出并知道您在做什么,那么您可能是对的,这就是为什么Linux内核中经常使用它的原因。
另一个原因是宏是无类型的,因此您可以这样做:
#define foo(x,t) do { t[x] = 0; } while (0)
它将适用于任何类型t。缺乏类型检查通常是一个缺点,但是在定义要使用任何类型的内容时它可能会很有用。
定义宏只是为了使代码更快是没用的.一个好的编译器将内联函数调用.但是,当您需要将结果用作常量时,宏可能很有用.
#define ENCODED(a,b,c,d) (((((((a)<<8)+b)<<8)+c)<<8)+d)
switch (a) {
   case ENCODED('f','o','o','0'):   ...
   case ENCODED('b', 'a', 'r', '1'): ...
}
如果要定义新标识符:
#define LIB_VERSION v101
#define VERSIONNED(x) x##LIB_VERSION
void VERSIONNED(myfunction)(int x) { ... }
当你想做一些其他的"魔法"时.例如:
#define assert(x) {if ((x) == 0) {printf("%s:%d: Assertion %s failed\n", __FILE__, __LINE__, #x); exit(-1); }}
当您想要定义使用多种类型的"通用"函数时.仅用于说明:
#define DELETE_LAST_ITEM(x) {while (x->next->next != NULL) x=x->next ; x->next = NULL}
可能还有其他一些我现在还不记得的情况.
| 归档时间: | 
 | 
| 查看次数: | 3789 次 | 
| 最近记录: |