与例如:
如何在VC++中毒化标识符?
在C++中"毒化一个函数"是什么意思?
有没有办法"正确"毒化一些声明(或实现)不受我控制的函数?
具体来说,我试图阻止某些Windows API函数的使用可能导致意外结果,例如CreateFileA
(使用T宏隐藏了混合ANSI和Unicode的事实)或SetWindowLong
(这将导致您的程序无声地失败,没有错误,也没有机会知道64位系统出了什么问题).
我对"正确"中毒的定义是,试图调用该函数会破坏构建时出现可读错误(如果错误发生在源代码中的正确位置,则奖励积分).
优选地,这应该是便携式的,并且至少它必须与GCC和clang一起工作.
到目前为止我尝试/看过的内容:
最简单,最明显的解决方案是利用预处理器:
#define CreateFileA __poison_ANSI_CreateFileA
这对于一个特定的函数以及其他几个函数非常有效,完全按照预期工作,具有提示问题的精确错误并指向源中的正确位置:
error: no matching function for call to '__poison_ANSI_CreateFileA' note: expanded from macro 'CreateFile' note: expanded from ... (precise location in source)
对于不同的功能,每个人都需要有一个唯一的名称,以避免冲突的定义错误,这是繁琐但容易完成的.到目前为止一切都那么好,除了它不适用于MinGW-w64标头本身使用可变参数宏篡改名称的函数,例如CreateWindow
或SetWindowLong
.无论如何,这些编译得很好,中毒与否.
#pragma GCC poison
铿锵碰巧也理解了(并且还有自己的版本),外观和声音应该完全符合我的要求,并以最惯用的方式.唉,它不起作用.或者说,它运作得太好了.
当中毒名称出现在声明中时,使用pragma指令中毒的函数已经触发错误,这意味着... 每次都在包含标题的每个构建中.这对编写程序没有多大帮助!
这些都有一个巨大的缺点,你必须完全复制类型定义,以免在合法的调用上出现"模糊函数调用"错误.另一方面,它们不起作用.clang抱怨__attribute__((__error__))
但忽略gnu::__error__
或gnu::error
同样gnu::deprecated
.此外,标准[[deprecated]]
都很好,但似乎没有什么(编译好,甚至没有警告?!).
有什么我能做的吗?