C++停止预处理器宏扩展
C++ Stop Preprocessor Macro Expansion
这是我的示例代码 https://godbolt.org/z/VKgKik
#define delete MyCustomDelete(__FILE__, __LINE__), delete
#define CAT(X,Y) CAT2(X,Y)
#define CAT2(X,Y) X##Y
#define CAT_3(X,Y,Z) CAT(X,CAT(Y,Z))
class A {
A() = CAT_3(de,le,te);
};
设置了 godbolt 示例以显示预处理器输出。目标是在预处理器传递结束时,我希望输出代码
class A {
A() = delete;
};
目前"这不应该出现"显示在那里。我以为使用 ## 运算符会阻止预处理器重新扩展,但事实并非如此。
我意识到删除"#define 删除"可以解决问题,但我需要在那里定义这个。我创建与删除同名的宏的原因是因为我希望能够跟踪新闻和删除,如果发生内存泄漏,我可以看到分配了哪一行代码。因此,此宏意味着我可以继续在我的代码中使用关键字 delete,并且免费填写文件和行号。据我所知,除了定义删除宏之外,没有其他方法可以实现此功能。这是问题的症结所在。删除宏为我提供了一个强大的调试工具,但它删除了一个有用的语言功能供我使用。
您没有机会通过展开宏来创建预处理令牌,该令牌是类似对象的宏的名称。n3337 的相关部分[cpp.rescan]
。我引用其中第一段的缩短部分。
替换列表中的所有参数并
#
和##
处理后 [...]。然后重新扫描生成的预处理令牌序列 [...] 以替换更多宏名称。
尽管存在delete
技术上禁止成为宏名称的问题,但无法阻止在重新扫描时识别宏名称。
您可能混淆了##
运算符确实使用其参数而不进行扩展的事实,并认为##
的结果不会进行宏扩展。
正如Michael Karcher的回答所述,你试图做的事情是不可能的:#define delete
已经使程序格式不正确,并且无法避免扩展类似对象的宏(在其自身扩展之外)。
但是,对于问题中详述的特定用例,可以使用解决方法。您可以将#define delete
放入头文件中(我们称之为debug_delete.hxx
),如下所示:
#ifdef delete
# undef delete
#endif
#define delete MyCustomDelete(__FILE__, __LINE__), delete
然后,创建另一个头文件(我们称之为normal_delete.hxx
):
#ifdef delete
# undef delete
#endif
特别要注意的是,这些标头中没有防止多重包含的机制;事实上,我们希望它们包含任意次数。
然后,将必须在适当的#include
指令中使用= delete;
的代码包装起来:
class A {
#include "normal_delete.hxx"
A() = delete;
#include "debug_delete.hxx"
~A() { delete p; }
};
(是的,它很丑陋,但你正在做的事情首先有点丑陋,所以可能需要丑陋的代码才能让它工作)。
大概您想使用宏,以便可以打开和关闭删除跟踪。如果您只在源上使用它,而不是尝试安装它来转换现有C++,则可以使用类似函数的宏来实现所需的可选跟踪。
#define TRACK_DELETES 0
#if TRACK_DELETES
#define DELETE( a )
do { MyCustomDelete( __FILE__, __LINE__ ); delete (a); } while (0)
#define DELETEALL( a )
do { MyCustomDelete( __FILE__, __LINE__ ); delete [] (a); } while (0)
#else
#define DELETE( a ) do { delete (a) ; } while(0)
#define DELETEALL( a ) do { delete [] (a) ; } while(0)
#endif
int main(){
DELETE( A );
DELETEALL( B );
return 0;
}
看看这是否在gcc -E
下将TRACK_DELETES设置为 0 或 1 的情况下满足您的需求。
您需要保留裸delete
关键字,以便可以适当地使用它。
- #定义c-预处理器常量..我做错了什么
- 预处理器:插入结构名称中的前一个行号
- 如何在c++中实现处理器调度模拟器
- 是否可以通过C++扩展强制多个python进程共享同一内存
- static_assert在宏中,但也可以扩展到可以用作函数参数的东西
- 如何将这个C++哈希表转换为动态扩展和收缩,而不是使用硬设置的最大值
- C/C++预处理器是否可以检测一些编译器选项
- 扩展光电二极管探测器以支持多个传感器
- 我可以转义(抑制)C预处理器宏扩展吗
- 预处理器,在未定义时将宏扩展为无
- C++停止预处理器宏扩展
- 预处理器宏可以只扩展一些粘贴的参数吗?
- 使用增强预处理器序列时,请避免扩展宏
- 检测导致代码大小大幅扩展的 C/C++ 预处理器滥用
- 如何使用 Boost 预处理器扩展字符串
- 如何查看使用 /P 扩展的预处理器宏
- MACRO扩展到预处理器块
- 预处理器#包括指令和宏扩展
- C预处理器扩展到另一个类似对象的宏
- c++预处理器延迟扩展问题