do{...}while(0)用法总结

1、消除冗余代码以及避免微妙的goto语句:

通常,如果一个函数开始要分配一些资源,然后如果在中途遇到错误则要退出函数,当然,退出前要释放资源

一般写法:

 1 int InitSomething()
 2 {
 3     char* pImage = NULL;
 4     char* pBitMap = NULL;
 5     char* pBuffer = NULL;
 6
 7     pImage = (char*)malloc(10);
 8     if(pImage == NULL)
 9     {
10         return -1;
11     }
12
13     pBitMap = (char*)malloc(20);
14     if (NULL == pBitMap)
15     {
16         free(pImage);
17         return -1;
18     }
19
20     pBuffer = (char*)malloc(1024);
21     if(NULL == pBuffer)
22     {
23         free(pImage);
24         free(pBitMap);
25         return -1;
26     }
27
28     ....
29
30
31     free(pImage);
32     free(pBitMap);
33     free(pBuffer);
34
35     return 0;
36 }

goto语句写法:

 1 int InitSomething()
 2 {
 3     char* pImage = NULL;
 4     char* pBitMap = NULL;
 5     char* pBuffer = NULL;
 6
 7     pImage = (char*)malloc(10);
 8     if(pImage == NULL)
 9     {
10         goto ret;
11     }
12
13     pBitMap = (char*)malloc(20);
14     if (NULL == pBitMap)
15     {
16         goto ret;
17     }
18
19     pBuffer = (char*)malloc(1024);
20     if(NULL == pBuffer)
21     {
22         goto ret;
23     }
24
25     ....
26
27     return 0;
28 ret:
29     if (pImage)
30     {
31         free(pImage);
32     }
33
34     if (pBitMap)
35     {
36         free(pBitMap);
37     }
38
39     if (pBuffer)
40     {
41         free(pBuffer);
42     }
43
44     return -1;
45 }

do...while(0)优化写法:

 1 int InitSomething()
 2 {
 3     char* pImage = NULL;
 4     char* pBitMap = NULL;
 5     char* pBuffer = NULL;
 6     int nRet = 0;
 7
 8     do
 9     {
10         pImage = (char*)malloc(10);
11         if(pImage == NULL)
12         {
13             nRet = -1;
14             break;
15         }
16
17         pBitMap = (char*)malloc(20);
18         if (NULL == pBitMap)
19         {
20             nRet = -1;
21             break;
22         }
23
24         pBuffer = (char*)malloc(1024);
25         if(NULL == pBuffer)
26         {
27             nRet = -1;
28             break;
29         }
30     }while(0);
31
32     if (nRet != 0)
33     {
34         if (pImage)
35         {
36             free(pImage);
37         }
38
39         if (pBitMap)
40         {
41             free(pBitMap);
42         }
43
44         if (pBuffer)
45         {
46             free(pBuffer);
47         }
48         return -1;
49     }
50
51     ....
52
53     return 0;
54 }

2、消除空声明在编译时出现警告:

#define FOOBAR do { } while(0)

3、消除代码块误用而产生的编译或运行时的错误:

#define swap(x,y) { int tmp; tmp=x; x=y; y=tmp; }

if (x > y)
    swap(x,y);
else
    dosth();
编译后预处理器替换的代码如下:
if (x > y)
    { int tmp; tmp=x; x=y; y=tmp; };
else//变成了悬空分支
    do_something();

错误出在分号“;”直接位于代码块的后面,解决的办法:宏定义嵌到do...while(0):
#define swap(x,y) do { int tmp; tmp=x; x=y; y=tmp; } while(0)

宏展开后的代码如下:
if (x > y)
    do { int tmp; tmp=x; x=y; y=tmp; } while(0);
else
    do_something();

4、消除条件语句中使用宏的隐患:

#define FOOBAR(x) \
    printf("parameter is %s\n", x);     do_sth(x)

如下代码片段
if (name == 2)
    FOOBAR("tcp");

宏展开后:
if (name == 2)
    printf("parameter is %s\n", "tcp");do_sth("tcp");

但实际上:if语句只作用于printf(), do_sth() 没按照原有意图一起受到条件的控制

重新定义宏:
#define FOOBAR(x) do{     printf("parameter is %s\n", x);     do_sth(x);}while(0)

代码片段展开:
if (name == 2)
    do{printf("arg is %s\n", "tcp"); do_sth("tcp");} while (0);

do{...}while(0)用法总结,布布扣,bubuko.com

时间: 2024-10-15 10:55:37

do{...}while(0)用法总结的相关文章

Vue1.0用法详解

Vue.js 不支持 IE8 及其以下版本,因为 Vue.js 使用了 IE8 不能实现的 ECMAScript 5 特性. 开发环境部署 可参考使用 vue+webpack. 基本用法 1 2 3 4 5 6 7 8 9 10 11 <div id="app"> {{message}} <input v-model="message"> </div> new Vue({ ele: '#app', data: { message:

js中 javascript:void(0) 用法详解(未整理)

javascript:void(0) 用于执行某些处理,但是不整体刷新页面的情况下使用. javascript:void(0)表示不做任何动作.如: <a href="javascript:void(0);" onclick="alert('ok');"></a> 这里表示这个链接不做跳转动作,执行onClick事件. 我想使用过ajax的都常见这样的代码: <a href="javascript:doTest2();void

vue2.0用法技巧汇总

1.class拼接: 2.select下拉截取: <template> <!--vip班支付报名页面--> <div id="payRecordMain"> <div class="pay_record_vip"> <div class="pay_message">报考城市<span class="cityName" v-text="cityName&

Vue-router(vue2.0)用法示例

一.新建3个组件 1./src/components/post.vue <template> <div> hello world! this is POST! </div> </template> <script> export default { } </script> 2./src/components/view.vue <template> <div> hello world! this is VIEW!

Android Studio 第八十二期 - Android Glide3.8.0用法大全支持九宫格

代码已经整理好,效果如下图: 地址:https://github.com/geeklx/myapplication2018/tree/master/p016_glide37_quan 原文地址:http://blog.51cto.com/liangxiao/2156107

python 3.0 字符串功能

字符传常用功能 方法描述 string.capitalize 把字符串的第一个字符大写 用法: name = 'fenggongzi'print (name.capitalize()) Fenggongzi string.center(width) 返回一个原字符串居中,并使用空格填充至长度 width 的新字符串 用法: name = 'fenggongzi'print (name.center(50,'#')) ####################fenggongzi##########

C++ STL replace()函数常用用法详解

replace算法: replace函数包含于头文件#include<string>中. 泛型算法replace把队列中与给定值相等的所有值替换为另一个值,整个队列都被扫描,即此算法的各个版本都在 线性时间内执行---其复杂度为O(n). 即replace的执行要遍历由区间[frist,last)限定的整个队列,以把old_value替换成new_value. 下面介绍replace()函数常用的九中方法: 用法一: 用str替换指定字符串从起始位置pos开始长度为len的字符 示例代码: #

do{}while(0)出现在cocos2dx

在学习cocos2dx内存管理的时候接触到了一个do{}while(0)用法. 具体是这样的:好多cocos2dx的类都有create方法,进去一看基本就是一个new操作,判断是否分配成功,成功就调用autorelease()之后返回这个新分配内存的地址:那么不成功呢?接着在cocos2dx-2.2.2版本中出现了一个宏定义CC_SAFE_DELETE(#define CC_SAFE_DELETE(p)            do { if(p) { delete (p); (p) = 0; }

linux find命令-print0和xargs中-0使用技巧(转载)

本文介绍了linux find命令中-print0和xargs中-0用法技巧,一些find命令的使用经验,需要的朋友参考下. 本节内容:linux find命令中-print0和xargs中-0的用法. 默认情况下, find命令每输出一个文件名, 后面都会接着输出一个换行符 ('n'), 因此find 的输出都是一行一行的: [bash-4.1.5] ls -ltotal 0-rw-r--r-- 1 root root 0 2010-08-02 18:09 file1.log-rw-r--r-