在 Linux 内核中,经常会看到do{} while(0)这样的语句,许多人开始都会疑惑,认为do{} while(0)毫无意义,因为它只会执行一次,加不加do{} while(0)效果是完全一样的,其实do {}while(0)的用法主要用于宏定义中。
这里用一个简单的宏来演示:
#defineSAFE_FREE(p)do{free(p);p=NULL;}while(0)
假设这里去掉do...while(0),即定义SAFE_DELETE为:
#defineSAFE_FREE(p)free(p);p=NULL;
那么以下代码:
if(NULL!=p) SAFE_DELETE(p) else .../*dosomething*/
会被展开为:
if(NULL!=p) free(p);p=NULL; else .../*dosomething*/
展开的代码中存在两个问题。
(1)、因为 if 分支后有两个语句,导致 else 分支没有对应的 if,编译失败。
(2)、假设没有 else 分支,则 SAFE_FREE 中的第二个语句无论 if 测试是否通过,都会执行。
的确,将SAFE_FREE的定义加上{}就可以解决上述问题了,即:
#defineSAFE_FREE(p){free(p);p=NULL;}
这样,代码:
if(NULL!=p) SAFE_DELETE(p) else .../*dosomething*/
会被展开为:
if(NULL!=p) {free(p);p=NULL;} else .../*dosomething*/
但是,在 C 程序中,每个语句后面加分号是一种约定俗成的习惯,那么,如下代码:
if(NULL!=p) SAFE_DELETE(p); else .../*dosomething*/
将被扩展为:
if(NULL!=p) {free(p);p=NULL;}; else .../*dosomething*/
这样,else 分支就又没有对应的 if 了,编译将无法通过。假设用了do {} while(0),情况就不一样了,同样的代码会被展开为:
if(NULL!=p) do{free(p);p=NULL;}while(0); else .../*dosomething*/
不会再出现编译问题。do while(0)的使用完全是为了保证宏定义的使用者能在不出现编译错误的情况下使用宏,它不对其使用者做任何假设。
审核编辑:刘清
-
C语言
+关注
关注
180文章
7618浏览量
138664 -
LINUX内核
+关注
关注
1文章
316浏览量
21860
原文标题:C语言-宏定义中使用do {...} while(0)到底图个啥
文章出处:【微信号:嵌入式那些事,微信公众号:嵌入式那些事】欢迎添加关注!文章转载请注明出处。
发布评论请先 登录
相关推荐
C语言中while和do-while循环的用法

评论