do{}while(0),在linux内核,C或C++开源的代码中,经常会遇到。代码如下:
do{
略;
}while(0)
代码在应用时,只执行一次循环体。
1、在C++中用作代码分块
do{}while(0)可用于代码分块,这样和{}的功能差不多,可以在块内定义局部变量,而不必担心命名冲突。
void Test(void)
{
int a = 10;
int b = 11;
do {
int a = 20; //在块内可以继续定义局部变量a,属于块内局部变量;
int b = 21; //在块内可以继续定义局部变量b,属于块内局部变量;
} while (0);
}
2、在linux,C或C++开源的代码中,可以用来定义更加复杂的宏,避免出错;
2.1、分析错误
#define MY_Function() Function1();Function2()
void Function1() {
printf("Function1 is working\n");
}
void Function2() {
printf("Function2 is working\n");
}
如果使用MY_Function()宏,替换后,就是"Function1();Function2();",看上去,好像没什么问题。但是如果放在if语句中,如果没有{},就会有问题。比如:
void Test(unsigned char x)
{
If(x) MY_Function();
}
替换后,如下:
void Test(unsigned char x)
{
If(x) Function1();Function2();
}
此时,if语句中只有"Function1();",没有"Function2();",发现和我们预期希望的结果不一样。
2.2、解决办法:
2.2.1、使用"{}",如下:
#define MY_Function() Function1();Function2()
void Test(unsigned char x)
{
If(x) { MY_Function(); }
}
替换后,如下:
void Test(unsigned char x)
{
If(x) { Function1();Function2(); }
}
2.2.2、使用"do{}while(0)",如下:
#define MY_Function() do { Function1();Function2(); }while(0)
void Test(unsigned char x)
{
If(x) MY_Function();
}
替换后,如下:
void Test(unsigned char x)
{
If(x) do { Function1();Function2(); }while(0);
}
3、起到goto的功能;
3.1、goto语句
下面的函数,需要用goto语句实现,如下:
void Function1() {
printf("Function1 is working\n");
}
void Function2() {
printf("Function2 is working\n");
}
void Test(unsigned char x)
{
If(x) goto EXIT;
Function();
EXIT:
Function2();
}
使用goto语句,会使得程序难以理解,同时修改困难。不建议使用。
3.2、"do{}while(0)"替换goto语句
void Function1() {
printf("Function1 is working\n");
}
void Function2() {
printf("Function2 is working\n");
}
#define MY_Function(x) do { if(x) break; Function1();}while(0)
void Test(unsigned char x)
{
MY_Function(x);
Function2();
}
替换后,代码如下:
void Test(unsigned char x)
{
do { if(x) break; Function1();}while(0);
//如果x=0,则退出循环,直接调用Function2(),相当于使用了goto语句。
Function2();
}
总结:
可见,"do{}while(0)"的作用,具有明显优势。