宏替换C ++运算符new [英] Macro to replace C++ operator new

查看:196
本文介绍了宏替换C ++运算符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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆