宏do{} while(0)的作用
宏do{} while(0)的作用
参考链接:https://github.tiankonguse.com/blog/2014/09/30/do-while.html
今天学到1个类函数宏,有很巧妙的用处:
#define FOO(X) do{ something; } while(0)
它至少有如下3种作用,分别是避免宏的错误使用、避免使用goto和对空宏的替代。
1 避免宏的错误使用
为了理解它,我们先从一个普通的类函数宏看起,假设函数体有多行代码:
#define FOO(X, Y) x++;y++;
int main(){
...
if (...)
FOO(x, y);
//上面代码会被展开为:
if (...)
x++;
y++;;
}
此时if只能限定1行代码,导致错误(我们可能会认为类函数宏FOO只有1行代码,所以在if出现时,可能不会用大括号将FOO括起来)。
于是我们将函数体用大括号括起来后,又出现了新的问题,我们一般习惯在宏的最后添加分号,所以出现如下情况:
#define FOO(X, Y) {x++;y++;}
int main(){
...
if (...)
FOO(x, y);
//上面代码会被展开为:
if (...){
x++;
y++;
}; //此处的分号编译报错
}
我们希望找到1个合适的宏定义,既有大括号,又能不受最后添加分号的影响,于是do {...;} while(0)的形式出现了。
它还有另一形式:#define FOO(X) if (1) { something; } else。
2 error跳转,避免goto的使用
非常巧妙!它可以作为goto语句的替代,从而满足编程规范的要求(禁止使用goto)。
goto语句一般用于出错时跳转到程序末尾,而循环break时,也是跳出循环(到达循环的"末尾")。由此,我们可以有如下代码:
使用goto的情况
void foo(){
if(error){
goto END;
}
dosomething...;
if(error){
goto END;
}
dosomething...;
END:
dosomething...;
return 0;
}
不使用goto的情况
int foo(){
do{
if(error) {
break;
}
dosomething...;
if(error){
break;
}
dosomething...;
}while(0);
dosomething...;
return 0;
}
3 替代空宏
空宏定义(编译报Warning):#define EMPTYMACRO
替代的空宏定义(无副作用):#define EMPTYMACRO do {} while (0)

浙公网安备 33010602011771号