do{
//do something
]while(0);
上面是一段使用 do while(0) 的代码,显然如上代码只会执行一次,这样使用显然是毫无意义的的(当然莫种情况下还是有意义的,比如在里面定义局部变量),所以在常规的代码编写中,我们并不会使用 do while(0) 这种结构。但是在Linux内核代码中却大量使用了do while(0) 这种结构:
那么,通常在什么时候使用呢,随便点击一个查看(其实其他都是同种类型):
细看,这居然是一个宏,(作为小白,平时的宏都是一行的),其实像这样复杂的宏,在内核源码中非常常用,可以使代码更加简洁,也不会像函数那样降低代码运行速度。那么为什么要使用 do while(0) 呢,我们使用一下例子分析:
例如我有这样一个宏:
void fun1(){
printf("fun1\n");
}
void fun2(){
printf("fun2\n");
}
#define ifTrue fun1(); fun2(); //复杂宏
那么如果我有一下这样的应用:
#define ifTrue fun1(); fun2();
if(flag)
ifTrue;
预编译展开宏之后:
#define ifTrue fun1(); fun2();
if(flag)
fun1();
fun2();
那么就会出现一个问题,无论flag是什么值 fun2() 都会被执行。程序逻辑就会错误。
所以有同学就说了,加个大括号不就行了吗?就像这样:
#define ifTrue {fun1(); fun2();} //复杂宏
那么,程序预编译展开宏之后将是这样:
#define ifTrue {fun1(); fun2();}
if(flag)
{fun1(); fun2();};
后面将多出一个分号(单独的分号代表空语句),对于现在9102的编译器当然没问题,但是对于旧编译器可能就会出现警告甚至是错误。怎么去将宏统一又能消化掉后面的分号呢,do while(0) 结构就很好的解决了上面的所有烦恼,do while() 设计的初心应该是循环控制结构,但是却被挖掘出另一种用途,这就是程序设计之美!