#define 宏实现函数功能可能存在的问题
#define 宏实现函数功能的问题
情形1
#define free_ptr(p) \
if(p) delete p; p = nullptr;
在调用free_ptr(p)的地方展开看这段代码:
if(p)
delete p;
p = nullptr;
其实判断条件if(p),只对delete p 有效。不管if(p)是否满足执行条件p =nullptr都会执行。这么写可能直观一点
if(p)
delete p;
p = nullptr;
显然这种操作和我们的意图是不一样的。
情形2
#define free_ptr(p) \
delete p; p = nullptr;
Object* p = new Object;
if(p) free_ptr(p);
展开代码:
Object* p = new Object;
if(p)
delete p;
p = nullptr;
显然这种操作也是不符合我们意图的。
情形3
#define free_ptr(p) \
if(p){\
delete p; p = nullptr;\
}
Object* p = new Object;
free_ptr(p);
展开调用代码:
Object* p = new Object;
if(p){
delete p;
p = nullptr;
}
可以实现意图。
情形4
#define free_ptr(p) \
do{\
delete p; p = nullptr;\
}while(0);
Object* p = new Object;
if(p) free_ptr(p);
展开调用代码:
Object* p = new Object;
if(p)
do{
delete p;
p = nullptr;
}while(0)
显然使用do{...}while(0), 可以实现意图。
使用宏来实现一个函数的功能是危险的,这么做的时候需要十分小心。相比于宏,可能使用内联函数更为妥当。
template<typename T>
inline void free_ptr(T** p)
{
if(*p)
{
delete *p;
*p = nullptr;
}
}
#define 宏实现函数功能可能存在的问题的更多相关文章
- #define宏定义形式的"函数"导致的bug
定义了一个宏定义形式的"函数": #define SUM8(YY)\ {\ int Y = YY>>2;\ ...\ } 然后使用的时候,传入了一个同名的变量Y: i ...
- C语言宏定义和宏定义函数
要写好C语言,漂亮的宏定义是非常重要的.宏定义可以帮助我们防止出错,提高代码的可移植性和可读性等. 在软件开发过程中,经常有一些常用或者通用的功能或者代码段,这些功能既可以写成函数,也可以封装成为宏定 ...
- #define宏定义
1 #define的概念 #define命令是C语言中的一个宏定义命令,它用来将一个标识符定义为一个字符串,该标识符被称为宏名,被定义的字符串称为替换文本. 该命令有两种格式:一种是简单的宏定义, ...
- iOS 7:漫谈#define 宏定义
#define宏定义在C系开发中可以说占有举足轻重的作用.底层框架自不必说,为了编译优化和方便,以及跨平台能力,宏被大量使用,可以说底层开发离开define将寸步难行.而在更高层级进行开 ...
- iOS 7:漫谈#define 宏定义(转)
iOS :漫谈#define 宏定义 #define宏定义在C系开发中可以说占有举足轻重的作用.底层框架自不必说,为了编译优化和方便,以及跨平台能力,宏被大量使用,可以说底层开发离开define将寸步 ...
- C 语言宏定义函数编写时 do-while 的妙用和一些注意事项
在 C 语言中,我们都知道可以用宏定义来编写函数,一般称为宏函数.如果一个宏函数比较复杂,那么在编写这样的宏函数是有一定技巧和注意事项的.文章给出一些我认为值得关注的地方,以及一些注意事项(个人建议) ...
- #define宏与const的区别
1.#define宏的用法 #define用宏名代替一个字符串,这样便于修改,提高了程序的可移植性.编译器在编译预处理时只对宏做文本替换,而不进行类型检查,所以替换后可能产生一些副作用. 带参数的宏类 ...
- c c++ #define 定义假函数
#define Add(a,b) ((a)+(b)) #define Max(a,b) ((a)>(b)?(a):(b)) 这就定义了一个假的函数 说白了就是字符串替换 这样在写代码时能 ...
- [ 随手记 1 ] C/C++宏,普通函数,内联函数
函数定义 C 语言中的函数定义的一般形式如下: return_type function_name( parameter list ) { body of the function } 在 C 语言中 ...
随机推荐
- UVa 213 信息解码 (模拟 && 二进制)
题意 :对于下面这个字符串 0,00,01,10,000,001,010,011……. 首先是长度为1的串,然后是长度为2的串,以此类推.不存在全为1的串. 你的任务是编写一个程序.首先输入一个代码头 ...
- Python3学习笔记(七):字典
在python中,有一种通过名字来引用值的数据结构,这种类型的数据结构成为映射. 字典是Python中唯一内建的映射类型,具有以下特点: 字典中的值是无序的 值存在特定的键(key)下 键(key)可 ...
- [CSP-S模拟测试]:666(模拟)
题目描述 不忘初心. 小$\pi$假期在家无聊,打开了某弹幕直播网站. 突然,有一个精彩的镜头. 小$\pi$看到了满屏的$6$,其中,有$666$.也有$666666$.也有$6666666666. ...
- Java缓存机制
1 Java缓存 1.1 jvm内置缓存 Java中实现缓存的方式有很多,比如用static hashMap基于内存缓存的jvm内置缓存,简单不实用,保对象的有效性和周期无法控制,容易造成内存急剧上升 ...
- StringBuffer的s1.capacity()是多少?
定义有StringBuffer s1=new StringBuffer(10);s1.append(“1234”)则s1.length()和s1.capacity()分别是多少? StringBuff ...
- 5.并发编程-synchronized 细节说明
并发编程-synchronized 细节说明 1. synchronized-锁重入 & 异常释放锁 说明 * 关键字synchronized 拥有锁重入的功能,也就是在使用synchroni ...
- 运行Spark官方提供的例子
去spark官网把spark下载下来: https://spark.apache.org/downloads.html 解压,可以看下目录: 其中examples目录下提供了java,scala,py ...
- fastJson对象转字符串首字母小写问题
特别提示:本人博客部分有参考网络其他博客,但均是本人亲手编写过并验证通过.如发现博客有错误,请及时提出以免误导其他人,谢谢!欢迎转载,但记得标明文章出处:http://www.cnblogs.com/ ...
- 使用NSIS脚本制作一个安装包
大部分人第一次看到NSIS脚本都是一脸懵逼的.因为它这个脚本的结构乍一看上去就非常奇怪,不作说明的话是看不懂的. 编写脚本命令的时候要非常注意,命令要按照规定写在脚本中不同的段落里,也就是说,命令的先 ...
- WAMP搭建与配置
使用WampServer整合软件包进行WAMP环境搭建 WampServer是一款由法国人开发的Apache Web服务器.PHP解释器以及MySQL数据库的整合软件包.免去了开发人员将时间花费在繁琐 ...