do{}while(0)只执行一次无意义?
时间:2023-08-18 11:00:05来源:面包芯语

意思是先干了再说!!

意思是先看看能不能干!


(资料图)

初见do{...}while(0)

linux内核和其他一些开源的代码中,经常会遇到这样的代码:

do{...}while(0)

这样的代码一看就不是一个循环,do..while表面上在这里一点意义都没有,只执行一次而已,那么为什么要这么用呢?

总结了7种妙处

实际上,do{...}while(0)的作用可不止一点点,下面我列举了一些。

do{CCImage*pImage=newCCImage();CC_BREAK_IF(NULL==pImage);bRet=pImage->initWithString(text,(int)dimensions.width,(int)dimensions.height,eAlign,fontName,(int)fontSize);CC_BREAK_IF(!bRet);bRet=initWithImage(pImage);CC_SAFE_RELEASE(pImage);}while(0);

举例来说,假设你需要定义这样一个宏:

#defineDOSOMETHING()action1();action2();

这个宏的本意是,当执行DOSOMETHING()时,action1(),action2()都会被调用。如果有判断,再执行这个宏的话,如下:

if(NULL==pPointer)DOSOMETHING();else...

这样宏在预处理的时候会直接被展开,放在花括号里,那么实际上写的代码如下:

if(NULL==pPointer)action1();action2();else...

这展开存在两个问题:

那么,仅仅使用{}把action1()、action2()包起来行么?比如:

#defineDOSOMETHING(){action1();action2();}

我们在写代码的时候都习惯在语句右面加上分号,如果在宏中使用{},代码编译展开后宏就相当于这样写了:{...};,展开后如下:

if(NULL==pPointer){action1();action2();};else...

这段代码中大括号后多了一个分号,如果有else,那么else又没有对应的if了,编译出错。

那么办法来了!

如果我们使用do{...}while(0)来定义宏,即:

#defineDOSOMETHING()\do{\action1();\action2();\}while(0)\

宏被展开后,上面的调用语句会保留初始的语义,同时绝大部分编译器都能够识别do{...}while(0)这种无用的循环并进行优化,不会导致性能优化的降低。

小结:

在Linux内核和驱动代码还有cocos2d-x中,很多宏实现都使用do{...}while(0)来包裹他们的逻辑,Google的Robert Love(先前从事Linux内核开发)给我们解答如下:

让你定义的宏总是以相同的方式工作,不管在调用代码中怎么使用分号和大括号,而该宏总能确保其行为是一致的。

do{执行.再执行…if(如果有什么条件满足){我想跳到另外一段代码了,剩下的不执行了,可是不建议用goto语句,怎么办呢?break;/*搞定*/}我有可能被执行.}while(false)

举个例子如下:

do{if(!a)break;//dosomethinghereif(!b)break;//doanotherthinghere}while(0);
#include#includeintmain(){char*str;/*最初的内存分配*/str=(char*)malloc(15);if(str!=NULL)gotoloop;printf("helloworld\n");loop:printf("mallocsuccess\n");return(0);}

但是,由于goto不符合软件工程的结构化,而且有可能使得代码难懂,所以很多人都不倡导使用,这个时候我们可以使用do{...}while(0)来做同样的事情:

#include#includeintmain(){do{char*str;/*最初的内存分配*/str=(char*)malloc(15);if(str!=NULL)break;printf("helloworld\n");}while(0);printf("mallocsuccess\n");return(0);}

这里将函数主体部分使用do{...}while(0)包含起来,使用break来代替goto,后续的清理工作在while之后,现在既能达到同样的效果,而且代码的可读性、可维护性都要比上面的goto代码好的多了。

inta;a=10;intb;b=20;

这种代码在只支持c89的编译器上是编译不过去的,比如ADS 2.0。

inta;a=10;do{intb;b=20;}while(0);
#defineDOSOMETHING()do{}while(0)

如果你有一个复杂的函数,变量很多,而且你不想要增加新的函数,可以使用do{...}while(0),将你的代码写在里面,里面可以定义变量而不用考虑变量名会同函数之前或者之后的重复,例如:

intkey;stringvalue;intfunc(){intkey=GetKey();stringvalue=GetValue();dosomethingforkey,value;do{intkey;stringvalue;dosomethingforthiskey,value;}while(0);}

但为了代码的可读性,尽量声明不同的变量名,以便于后续开发人员欣赏。

标签:

  • 上一篇文章: 二月红有没有后代(二月红的后代)
  • 下一篇文章: 最后一页
  • 最新
  • do{}while(0)只执行一次无意义?

    在嵌入式开发中,宏定义非常强大也非常便捷,如果正确使用可以让你的工

  • 二月红有没有后代(二月红的后代)

    导读1、演员张艺兴二月红出身戏曲世家,唱旦角,行二,所以艺名二月红

  • 书写美丽中国新画卷——习近平总书记引领生态文明建设的故事

    2023年8月15日,是首个全国生态日。18年前,习近平同志在浙江工作期间

  • 7月社融数据不及预期 二级债基指数周跌幅超0.5%

    上周五,7月社融数据公布之后,不及市场预期,债市收益率呈现快速下行

  • 青村镇斩获“金银铜”奖!快来看看谁是新“桃王”→

    8月12日下午,“桃你欢心”2023年奉贤黄桃派对暨第十九届擂台赛在金汇

  • 瓜达尔港中方车队遇袭受枪击现场图片曝光!弹孔清晰可见 具体是什么情况?

    【瓜达尔港中方车队遇袭受枪击,现场图片曝光!弹孔清晰可见】具体的是

  • 何流清(何流)

    何流清,何流这个很多人还不知道,现在让我们一起来看看吧!1、答案:风

  • 战锤40k《永恒女王》同人文翻译 第五十三章

    奥林匹斯山的锻造厂,建在火星最大的山的周围和内部,是机械的跳动的心

  • 港股异动 | 邮储银行(01658)跌近4%领跌内银股 存量按揭降息影响银行盈利 但负面影响有限

    内银股早盘普跌,截至发稿,邮储银行(01658)跌3 45%,报4 48港元;招商

  • 业绩快速增长,奥赛利定等新药获批上市

    恩华药业(002262)投资要点事件:公司发布2023年半年报,实现营业收入24

  • 《暗黑4》第一赛季翻车:暴雪紧急招聘赛季设计师

    伴随着《暗黑破坏神4》的1 1补丁上线,游戏中大量的强力Build和职业伤

  • 生活中哪些人容易被慢性胃炎盯上?医生:4类人要提高警惕

    生活中哪些人容易被慢性胃炎盯上?医生:4类人要提高警惕,幽门,胃癌,生

  • 文旅部:将启动新一批国家级旅游度假区等建设工作

    今年以来,人们的旅游需求得到了集中释放,许多旅游景区重现了“人山人

  • 实时焦点:​正阳县新阮店乡:党员先行 扮靓乡村

    近日,适逢正阳县新阮店乡每周五全域环境卫生整治大扫除周末义务劳动日

  • “数字监管”让跨境贸易更便利

    “数字监管”让跨境贸易更便利(主题)深圳特区报讯(记者方慕冰)打开

  • 失业超过60天还能申领失业保险吗?离职8个月了还能领失业金吗?

    失业超过60天还能申领失业保险吗可以。根据官方最新回应,任何单位

  • 旅游
    • 每日热点:生育基金需要交社保几个月可以领取?灵活就业社保可以买生育险吗?

    • 安徽农金易贷卡办理条件是什么?如何办理安徽农金易贷卡?

    • 天天微资讯!增发股票的意思怎么理解?股票非公开增发是什么意思?

    • 全球快看点丨前鼻音和后鼻音有哪些区分技巧_前鼻音和后鼻音有哪些