关于宏的一些内容的总结

1. 为什么宏定义里经常出现 do {...} while (0) 

Answer:

用一句话概括就是:使用do{...}while(0)构造后的宏定义不会受到大括号、分号等的影响,总是会按你期望的方式调用运行。

比如

#define foo(x) i++; i--

如下调用

foo(wolf);

就会被扩展为

i++; i--;

但是如果这样调用

if (!feral)

    foo(wolf);
 那么扩展后就是

if (!feral)

    i++;

i--;

不符合原意了。

 

那么为什么不用大括号直接把宏包围起来呢?例如:

#define foo(x) { i++; i--; }

考虑如下情况:

if (!feral)

    foo(wolf);
else
    bin(wolf);
 
扩展后为:
if (!feral) {
    i++;
    i--;
};
else
    bin(wolf);
 
就有语法错误了。
 
所以,Linux和其它代码库里的宏都用do/while(0)来包围执行逻辑,因为它能确保宏的行为总是相同的,而不管在调用代码中使用了多少分号和大括号。
 
其他 do {...} while (0) 的作用包括:
1. 使用break来代替goto的跳转,比如:
int foo() 
{ 
    somestruct* ptr = malloc(...); 
    
    dosomething...; 
    if(error) 
    { 
        goto END; 
    } 
    
    dosomething...; 
    if(error) 
    { 
        goto END; 
    } 
    dosomething...; 
    
END: 
    free(ptr); 
    return 0; 
    
} 

替换为

int foo() 
{ 
    
    somestruct* ptr = malloc(...); 
    
    do{ 
        dosomething...; 
        if(error) 
        { 
            break; 
        } 
    
        dosomething...; 
        if(error) 
        { 
            break; 
        } 
        dosomething...; 
    }while(0); 
    
    free(ptr); 
    return 0; 
    
} 

 

2. 避免变量作用域的冲突,在 do{}while(0) 定义变量

 

3. 可以定义空的宏(避免警告)

#define EMPTYMICRO do{}while(0) 

 

posted @ 2016-04-27 23:20  blcblc  阅读(254)  评论(0编辑  收藏  举报