关于#pragma push_macro("new")

该博客探讨了在C++中使用#pragma push_macro("new")和#undef new的用法,以临时替换关键字new的宏定义。文章指出,尽管宏定义名与关键字new相同不会导致编译错误,但可能导致预期外的行为。通过示例展示了如何使用#pragma push_macro和pop_macro恢复宏定义,以防止影响关键操作。同时,讨论了重载operator new的目的,特别是调试时添加文件名和行号信息的功能。

在三方库源码中,我们经常看到这样的代码:

#pragma push_macro("new")

#undef new

// do something with new

......

#pragma pop_macro("new")

它的作用就是将宏定义new压入栈并取消它的定义,如此一来new的本来含义便获得了恢复,使用完毕后将宏定义new弹出栈,恢复宏定义。

不过,仍有下面两个问题需要回答。

1)宏定义名不会与关键字new冲突吗?

2)宏定义new有何作用?

问题1

宏定义名若与保留的关键字相同,编译器并不会提示错误,而是用最新定义的宏定义代替关键字发挥作用。下面是一个例子,定义了宏int。例程能顺利通过编译链接,其运行结果为8和4,与预期相同。

// by btwsmile
#include <iostream>
using namespace std;
#define int double
void main()
{
 int iOne = 1;
 cout<<sizeof(iOne)<<endl;
#pragma push_macro("int")
#undef int
 int iTwo = 2;
 cout<<sizeof(iTwo)<<endl;
#pragma pop_macro("int")
}

问题2

我们知道operator new是可被重载的,重载的operator new可以包含多个参数。比如定义在atldbgmem.h中的new,其签名式为:

void* operator new(size_t nSize, LPCSTR lpszFileName, int nLine); // 3个参数

其中nSize为数据类型的字节数,new被调用时,nSize被自动配置,因此在调用它时,我们无需指定nSize参数,仅提供后两个参数即可。

在atldbgmem.h中还发现宏定义new:

#define new new(__FILE__, __LINE__)

其中,__FILE__和__LINE__是编译器预定义宏,分别表示当前文档的名称(LPCSTR类型)、当前行行号(int类型),它们被当作实参传入重载的new,这样做是为了实现某些调试功能。

显然,new的本来含义被宏定义覆盖了,当我们需要使用new的本来含义时,就需使用到push_macro("new")的技巧。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值