CCImage* pImage = new CCImage();
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);
为了宏展开的时候不会出错。如果直接放在花括号里会出错的
举例来说,假设你需要定义这样一个宏:
#define DOSOMETHING() action1(); action2();
这个宏的本意是,当执行DOSOMETHING()时,action1(),action2()都会被调用。如果有判断,再执行这个宏的话,如下:
if(NULL == pPointer)
DOSOMETHING(); else ...
这样宏在预处理的时候会直接被展开,放在花括号里,那么实际上写的代码如下:
if(NULL == pPointer)
action1();
action2(); else ...
这展开存在两个问题:
因为if分支后面有两个语句,导致else分支没有对应的if,编译失败。
假设没有else分支,则DOSOMETHING中的第二个语句无论if测试是否通过,都会执行。
那么仅仅使用{}把action1()、action2()包起来行么?比如:
#define DOSOMETHING() { action1(); action2(); }
我们在写代码的时候都习惯在语句右面加上分号,如果在宏中使用{},代码编译展开后宏就相当于这样写了:
{...};,展开后如下:
if(NULL == pPointer)
action1();
action2();
}; else ...
这段代码中大括号后多了一个分号,如果有else,那么else又没有对应的if了,编译出错。
那么办法来了
如果我们使用
do{...}while(0)来定义宏,即:
#define DOSOMETHING() \ do{ \
action1();\
action2();\
}while(0)\
宏被展开后,上面的调用语句会保留初始的语义,同时绝大部分编译器都能够识别
do{...}while(0)这种无用的循环并进行优化,不会导致性能优化的降低。
在Linux内核和驱动代码还有
cocos2d-x中,很多宏实现都使用
do{...}while(0)来包裹他们的逻辑,Google的
Robert Love(
先前从事Linux内核开发
)给我们解答如下:
让你定义的宏总是以相同的方式工作,不管在调用代码中怎么使用分号和大括号,而该宏总能确保其行为是一致的。
/* 最初的内存分配 */
str = (char *) malloc(15);
if
(str != NULL)
goto loop;
printf
(
"hello world\n"
);
loop:
printf
(
"malloc success\n"
);
return
(0);
但由于goto不符合软件工程的结构化,而且有可能使得代码难懂,所以很多人都不倡导使用,这个时候我们可以使用
do{...}while(0)来做同样的事情:
#include #include int main()
{ do{
char *str;
/* 最初的内存分配 */
str = (char *) malloc(15); if(str != NULL) break; printf("hello world\n");
}while(0); printf("malloc success\n"); return(0);
这里将函数主体部分使用do{...}while(0)包含起来,使用break来代替goto,后续的清理工作在while之后,现在既能达到同样的效果,而且代码的可读性、可维护性都要比上面的goto代码好的多了。
可以是兼容各种编译器
int a;
a = 10;
int b;
b = 20;
这种代码在只支持c89的编译器上是编译不过去的,比如ADS 2.0。
int a;
a = 10; do {
int b;
b = 20;
}while(0);
避免由宏引起的警告 内核中由于不同架构的限制,很多时候会用到空宏。在编译的时候,这些空宏会给出警告,为了避免这样的warning,我们可以使用
do{...}while(0)来定义空宏:
#define DOSOMETHING() do{}while(0)
定义单一的函数块来完成复杂的操作
如果你有一个复杂的函数,变量很多,而且你不想要增加新的函数,可以使用do{...}while(0),将你的代码写在里面,里面可以定义变量而不用考虑变量名会同函数之前或者之后的重复,例如
int key;
string value;
int func()
int key = GetKey();
string value = GetValue();
dosomething for key,value; do{
int key;string value;
dosomething for this key,value;
}while(0);
但是为了代码的可读性,尽量声明不同的变量名,以便于后续开发人员欣赏。
在工业自动化领域,工控机是不可或缺的核心设备之一。传统工控机长期以来占据主导地位,然而,随着科技的不断进步与创新,嵌入式工控机逐渐崭露头角,成为工业控制领域中备受关注的新趋势。本文将详细探讨嵌入式工控机与传统工控机相比具...
工业自动化
“第五届国产嵌入式操作系统技术与产业发展论坛暨嵌入式系统联谊会主题讨论会(总第29次)”主要聚焦“面向异构多核智能芯片的混合关键系统研究与应用”这一会议主题。主办方邀请到来自华东师大、湖南大学、中山大学、复旦大学和北京航...
工控机是专门应用于工业控制领域的计算机设备,也被称为工业计算机或嵌入式工控计算机。它在工业自动化、过程控制、设备监测和数据采集等方面发挥着重要作用。工控机具有一些独特的特点和功能,下面将详细介绍。
2023年8月14日 – 提供超丰富半导体和电子元器件的业界知名新品引入 (NPI) 代理商贸泽电子 (Mouser Electronics) 宣布2023上半年增加了29家新制造商合作伙伴,继续扩大其产品供应阵容。贸泽...
随着电动车的普及和环保意识的增强,充电桩作为电动车充电设备的重要一环,充电桩行业正迅速发展,消费市场的大量应用也造就市场的需求量不断增长。因此,产品的功能、可靠性、安全性等要求也变得尤为重要,而采用传统单片机产品并不能满...
第五届国产嵌入式操作系统技术与产业发展额论坛暨嵌入式系统联谊会主题讨论会(总第29次)将于2023年8月12日在北京航空航天大学杭州创新研究院举办,同时设有嵌入式操作系统、异构多核智能芯片和软件生态的海报展示区。
随着科技的不断进步,Flash存储器作为一种重要的存储技术逐渐得到广泛应用。它的高速、稳定和高密度的特点,使得它在多个领域都有重要的应用。本文将着重介绍Flash存储器在电子产品、计算机系统和嵌入式系统等多个方面的应用。
雷达和超声波有什么区别?雷达天线系统了解吗?
什么是雷达感知技术?雷达应用领域有哪些?
TrendForce集邦咨询:电视面板价格续涨加上市场需求保守,全年电视出货预估下修至1.98亿台
如何调节PID控制器参数?PID控制器有哪些作用?
你搞懂PID控制原理没?PID控制器有哪些优缺点?
如何确定PID控制器初始参数?如何选择PID?
以太网拓扑结构了解吗?工业以太网可扩展性考虑过吗?
本站介绍 | 申请友情链接 | 欢迎投稿 | 隐私声明 | 广告业务 | 网站地图 | 联系我们 | 诚聘英才
京ICP备11013301号
京公网安备 11010802024343号