do {…} while (0) 的作用
这篇文章主要讲讲do{…}while(0)在C/C++编程中的应用。
- do {…} while (0)作为宏定义使用
- do {…} while (0)替代GOTO
do {…} while (0)作为宏定义使用
在Linux内核和很多C库中常常能见到do {…} while (0)这种宏定义的使用,那么这么用究竟有什么作用呢?下面来直接看代码。
C++代码示例
#include "stdafx.h"
#define test(x) test1(x); test2(x); //1
//#define test(x) do{test1(x); test2(x);}while(0) //2
void test1(char * x)
{
printf("test1 %s \n",x);
}
void test2(char * x)
{
printf("test 2 %s \n",x);
}
int main()
{
char szTest[10] = "hello";
test(szTest); // 3
if (true)
test(szTest); //4
//{test1(x); test2(x);};
else
test(szTest); //5
//{test1(x); test2(x);};
return 0;
}
上述代码如果宏定义如标号1所示则 3 处能正确运行,标号4、5处宏展开后如注释掉的代码所示,会导致编译错误,如果宏定义改为如标号2所示do {…} while (0),则代码正常运行。
总结do {…} while (0)让你定义的宏总是以相同的方式工作,不管怎么使用宏,不管宏定义展开后是否会与代码段产生冲突,宏定义都可以正常工作。
do {…} while (0)替代GOTO
C++代码示例
#include "stdafx.h"
#include <malloc.h>
int test_goto()
{
int *ptr = (int *)malloc(20);
if(!ptr)
goto _end;
_end:
free(ptr);
return 0;
}
int test_dowhile()
{
int *ptr = (int *)malloc(20);
do
{
if(!ptr)
break;
}while(0);
free(ptr);
return 0;
}
int main()
{
test_goto();
test_dowhile();
return 0;
}
工程中我们经常需要在函数结束的时候进行必要的清理工作,而这时候goto语句用起来会非常的舒服,如上述代码中test_goto()的代码示例,然而goto并不符合现代化软件工程结构化的思想,因此很多大公司会禁用goto语句,这时候do {…} while (0)就可以出场了,如上述代码test_dowhile()所示,do {…} while (0)配合break可以起到如goto的一样的效果。
当然个人认为还是goto的代码看起来比较舒服,当函数短小,跳转不多的时候选择goto问题也不是太大,这个具体看个人选择。