是否有可能在同一个char序列上有类似函数的宏和类似对象的宏?

时间:2017-10-13 13:47:44

标签: c++ macros

我的问题是这个 - 我试图制作一个堆检查器用于测试和此

a)重载标准的全局新/删除操作符,以便他们让我的自定义类知道每个alloc和delete

b)添加具有

签名的自定义新运算符
void* operator new(size_t size, const char* filename, const char* function, int line)

c)创建一个宏,用我的新调用和给定文件func&替换标准新调用。线

#define new new(__FILE__, __FUNCTION__, __LINE__)
  • 这种方法很有效,除非有人在类中使用自定义new或直接使用运算符new() - 这意味着我只能在加载标准C ++库后定义此宏(功能,algo,string ...),因为他们很擅长做那些事情

d)所以我们想出了使用var-arg宏来解决这些问题的好主意

#define new(...) new(__VA_ARGS__, __FILE__, __FUNCTION__, __LINE__)
  • 这适用于最后一点的所有问题案例,因为任何参数都传递给 new(someargs)或operator new(size_t,someargs)被var-arg宏替换并发送到我的自定义新运算符

  • 它不适用于最常见的只是打电话的情况:

int * ptr = new int;

  • 因为电话没有括号,因此未将其扩展为功能宏

这让我想到标题中提到的问题: 有没有办法用宏来做这个,这样一个人可以用原始代码替换相同的字符序列,无论它是在没有参数列表的情况下调用还是用一个?

在这种情况下,期望的结果是:

新的没有括号 - new -> new(__file__, __func__, __line__)

新的括号后面 - new(args) -> new(args, __file__, __func__, __line__)

我意识到这是尝试重新定义相同宏的明显情况,所以它不可能。我正在寻找一些可以让我解决这个问题的预处理器魔法。

免责声明:我知道它很丑陋,我们实际上只是忽略标准库 new 来解决c)中的解决方案。但是,正如我确实花了一些时间研究这种可能性,如果有人有可能做到这一点,我会感兴趣。

麦片!

___ EDIT ___ 请不要专注于我想要完成的事情,而只关注标题中的问题。堆检查器本身可以采用各种符合标准的方式实现,而这不是其中之一:)我更多的是我对使用预处理器弯曲语言的可能性有多大的好奇心

问题所在 - 我可以使用一些预处理器命令来实现相同序列的不同行为,在它之后有括号和没有括号(也就是说,就像我同时具有类似函数和类似对象的宏一样同名)

感谢所有答案:)

1 个答案:

答案 0 :(得分:0)

不,你不能。参见C ++标准的§16.3p2[cpp.replace](其他版本和C标准的等效部分中的类似措辞;没有任何改变)(强调我的):

  

当前定义为类似对象的宏(见下文)的标识符可以由另一个#define预处理指令重新定义,前提是第二个定义是类似于对象的宏定义和二   替换列表是相同的,否则程序是不正确的。同样,当前定义为类似函数的宏(见下文)的标识符可以由另一个#define预处理指令重新定义,前提是第二个定义是类似函数的宏定义,它具有相同数量和参数拼写,两个替换列表相同,否则程序格式不正确。

换句话说,宏标识符可以是类似对象的,也可以是类似函数的,但不能同时使用相同的标识符。