#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 语言中 ...
随机推荐
- java 用redisTemplate 的 Operations存取list集合
一 .存取为list类型 @RestController @RequestMapping("/test") @Slf4j public class TestController { ...
- python数据类型之 元祖、列表字典
Python中元祖,列表,字典 Python中有3种內建的数据结构:列表.元祖和字典: 1.列表 list是处理一组有序项目的数据结构,即你可以在一个列表中存储一个序列的项目. 列表中的项目应该包 ...
- Android NDK下载
http://dl.google.com/android/ndk/android-ndk-r10d-linux-x86_64.bin https://dl.google.com/android/rep ...
- gunicorn+nginx配置方法
对于gunicorn+nginx的配置,理解他们之间的关系很重要,以及最后如何确认配置结果是正确的也很重要 nginx 配置文件: 修改这个配置文件有3个用处: 假设服务器本身的Ip是A称为ip-A, ...
- SpringBoot -- 配置mysql、hibernate
# application.properties# Server settings (ServerProperties)server.port=8081server.address=127.0.0.1 ...
- js验证:密码只能为大写字母+小写字母+数字的8至15位字符组合
var reg = /^(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])[a-zA-Z0-9]{8,15}$/; // alert(password); if(reg.test(pa ...
- Unity3D-Canvas-UIScaleMode
UnityCanvasUI自适应部分 用Canvas下的自适应UI Scale Mode: Constant Pixel Size:固定像素大小,无论如何UI怎么样就怎么样,只能通过 Scale Fa ...
- jQuery验证控件jquery.validate.js汉化
如需要修改,可在js代码中加入: jQuery.extend(jQuery.validator.messages, { required: "必选字段", remote: &q ...
- database 学习
ref : 什么是NoSQL,为什么要使用NoSQL?
- 用seaborn对数据可视化
以下用sns作为seaborn的别名 1.seaborn整体布局设置 sns.set_syle()函数设置图的风格,传入的参数可以是"darkgrid", "whiteg ...