C语言中宏定义(#define)时do{}while(0)的价值

最近在新公司的代码中发现处处用到do{...}while(0),google了一下,发现Stack Overflow上早有不少讨论,总结了一下讨论,加上本身的理解,do{...}while(0)的价值主要体如今:程序员

1. 增长代码的适应性google

下面的宏定义没有使用do{...}while(0)spa

#define FOO(x) foo(x); bar(x);

这样宏定义,单独调用不会出现问题,例如:code

FOO(100)

宏扩展后变成:blog

foo(x);bar(x);

 这样调用FOO没有任何问题,可是FOO(x)不能放入控制语句中,例如编译器

if (condition)
    FOO(x);
else 
    ...;

通过宏扩展后,变成了it

if (condition)
    foo(x);bar(x);
else 
    ...;

这样就致使了语法错误,语法错误并不可怕,在编译阶段就能发现,更致命的是他有可能致使逻辑错误,这种错误编译器发现不了,一出这种问题,程序员就抓狂吧。例如:  io

if (condition)
    FOO(x);

这段代码通过扩展后变成:编译

if (condition)
    foo(x); bar(x);

这样一来,不管condition是true仍是false,bar(x)都会被调用。有没有被这煎熬过的兄弟啊?class

这时候do{...}while(0)的价值就体现出来了,修改一下FOO的定义

#define FOO(x) do { foo(x); bar(x); } while (0)

这样FOO,放入控制语句中就没有问题了。

也许有人说:把foo(x);bar(x)用大括号括起来不就好了吗?好比这样定义:

#define FOO(x) { foo(x); bar(x); }

再看下面代码:

if (condition)
    FOO(x);
else 
    ...;

扩展后:

if (condition)
    {foo(x);bar(x);} ; //注意最后这个分号,语法错误
else 
    ...;

照样语法错误;

2.增长代码的扩展性

我理解的扩展性,主要是宏定义中还能够引用其余宏,好比:

#define FOO(x) do{OTHER_FOO(x)} while(0)
这样咱们不用管OTHER_FOO是但语句仍是符合语句,都不会出现问题

3.增长代码的灵活性

 灵活性主要体如今,咱们能够从宏中break出来,例以下面的定义:

#define FOO(x)  do{ \
    foo(x);  \
    if(condition(x)) \
        break; \
    bar(x) \
    ..... \} while(0)
相关文章
相关标签/搜索