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

Posted

技术标签:

【中文标题】是否可以在同一个字符序列上有一个类似函数的宏和一个类似对象的宏?【英文标题】:Is it possible to have a function-like macro and an object-like macro over the same char sequence? 【发布时间】:2017-10-13 13:47:43 【问题描述】:

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

a) 重载标准全局 new/delete 运算符,以便它们让我的自定义类知道每个 alloc 和 delete

b) 添加具有类似

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

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

#define new new(__FILE__, __FUNCTION__, __LINE__)
这很好用,除非有人在类中使用自定义 new 或直接使用 operator new() - 这意味着我只能在加载标准 C++ 库(函数式, 算法, 字符串...),因为他们在做这些事情上很投入

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

#define new(...) new(__VA_ARGS__, __FILE__, __FUNCTION__, __LINE__)

这适用于最后一点中的所有有问题的情况,因为任何参数都传递给 new (someargs) 或运算符 new(size_t, someargs) 被 var-arg 宏替换并发送到我的自定义新运算符中

但是它不适用于最常见的调用情况:

int* ptr = new int;

因为 new 调用没有括号,因此它没有扩展为函数宏

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

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

new 后面没有括号 - new -> new(__file__, __func__, __line__)

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

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

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

干杯!

___编辑___ 请不要专注于我想要完成的事情,而只关注标题中的问题。 Heap Checker 本身可以以多种符合标准的方式实现,这不是其中之一 :) 更多的是我对预处理器可以在多大程度上改变语言的好奇心。

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

感谢任何和所有的答案:)

【问题讨论】:

用宏重新定义关键字(new) 是未定义的行为。 有什么理由不能直接覆盖/重载函数?无论如何,宏通常都是邪恶的。 @NathanOliver 能否提供对 C++ 标准的参考? 另见:***.com/q/9109377/2785528 @tommybazar valgrind 是一个选项吗?如果您使用调试符号编译程序,valgrind --tool=memcheck --leak-check=full --show-leak-kinds=all 将为您提供非常详细的分配概览 【参考方案1】:

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

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

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

【讨论】:

以上是关于是否可以在同一个字符序列上有一个类似函数的宏和一个类似对象的宏?的主要内容,如果未能解决你的问题,请参考以下文章

同名的类函数宏和枚举器

类函数宏和变量

毒瘤header(代码里的宏和函数看不懂可以来这里找)

是否有用于从 julia 中的类似生成器的函数创建快速迭代器的宏?

Confluence 6 自定义 Decorator 模板的宏和针对高级用户

Confluence 6 自定义 Decorator 模板的宏和针对高级用户