宏替换C ++运算符new [英] Macro to replace C++ operator new
问题描述
是否可以创建宏来替换所有形式的运算符new
,其中包含额外的args ...例如 __ FILE __
和 __ LINE __
?
麻烦似乎是 code>可以使用或不使用括号进行编码,因此:
-
>宏:
#define new new(__ FILE__,__LINE__)
将替换以下声明:
A * a = new A ();
-
和类似功能的宏:
#define new(A)new(A,__FILE__,__LINE__)
>
将替换以下声明:
A * a = new Nothrow)A();
不幸的是,具有相同的标识符的宏,即使它们具有不同的类型,因此下列操作失败:
#define new new(__ FILE__,__LINE__)
#define new(A)new(A,__FILE__,__LINE__)//错误:已定义new
因为我使用g ++我希望使用他们的语法 variadic宏会产生成功,但不幸的是,。以下:
#define new(...)new(__ FILE__,__LINE__,## __VA_ARGS__)
只匹配 new(xyx)A()
,而不是 new A()
。
我知道已经写了为什么这是不可能的,但我觉得我这么近必须有办法。
这里是我使用的:
在new.cpp
const char * __file__ =unknown
size_t __line__ = 0;
void * operator new(size_t size){
void * ptr = malloc(size);
record_alloc(ptr,__ file __,__ line__);
__file__ =unknown;
__line__ = 0;
return ptr;
}
void delete(void * ptr)
{
unrecord_alloc(ptr);
free(ptr);
}
对于紧凑性,我省略new和delete的其他定义。 record_alloc和unrecord_alloc是保存包含ptr,line和file的结构链表的函数。
$ new $ h $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $$ b
extern const char * __file__;
extern size_t __line__;
#define new(__file __ = __ FILE __,__ line __ = __ LINE__)&& 0? NULL:new
对于g ++,new只扩展一次。关键是&& 0,这使它为假,并导致使用真正的新。例如,
char * str = new char [100];
由预处理器扩展为
char * str =(__file __ =somefile.c,__ line __ = some_number)&& 0? NULL:new char [100];
因此,记录文件和行号,并调用您的自定义新函数。
这适用于任何形式的new - 只要在new.cpp中有一个相应的形式
Is it possible to create macros to replace all forms of operator new
with overloads that include additional args...say __FILE__
and __LINE__
?
The trouble appears to be that operator new
can either be coded with or without parentheses, therefore:
object-like macros:
#define new new(__FILE__, __LINE__)
will replace declarations like:
A* a = new A();
and function-like macros:
#define new(A) new (A, __FILE__, __LINE__)
will replace declarations like:
A* a = new(std::nothrow) A();
Unfortunately it's an error to attempt to declare two macros with the same identifier, even if they are of different types, so the following fails:
#define new new(__FILE__, __LINE__)
#define new(A) new (A, __FILE__, __LINE__) // Error: "new" already defined
Since I'm using g++ I was hopeful that employing their syntax of variadic macros would yield success, but unfortunately not. The following:
#define new(...) new(__FILE__, __LINE__, ## __VA_ARGS__)
only matches new(xyx) A()
, not new A()
.
I know that essays have been written about why it is impossible, but I feel like I'm so close that there must be a way. Is there anything obvious that I'm missing?
Here is what I use:
In new.cpp
const char* __file__ = "unknown";
size_t __line__ = 0;
void* operator new(size_t size) {
void *ptr = malloc(size);
record_alloc(ptr,__file__,__line__);
__file__ = "unknown";
__line__ = 0;
return ptr;
}
void delete(void *ptr)
{
unrecord_alloc(ptr);
free(ptr);
}
For compactness, I'm leaving out the other definitions of new and delete. "record_alloc" and "unrecord_alloc" are functions that maintain a linked list of structure containing ptr, line, and file).
in new.hpp
extern const char* __file__;
extern size_t __line__;
#define new (__file__=__FILE__,__line__=__LINE__) && 0 ? NULL : new
For g++, "new" is expanded only once. The key is the "&& 0" which makes it false and causes the real new to be used. For example,
char *str = new char[100];
is expanded by the preprocessor to
char *str = (__file__="somefile.c",__line__=some_number) && 0 ? NULL : new char [100];
Thus file and line number are recorded and your custom new function is called.
This works for any form of new -- as long as there is a corresponding form in new.cpp
这篇关于宏替换C ++运算符new的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!