功能中毒在 C++ 中是非常有用的技术。
一般来说,它指的是使某个功能不可用,例如如果您想禁止在程序中使用动态分配,您可以"poison"malloc 函数因此无法使用。“中毒”标识符意味着“中毒”之后对标识符的任何引用都是硬编译器错误
例如(参见现场演示here)
#include <iostream>
#include <cstdlib>
#pragma GCC poison malloc
int main()
{
int* p=(int*)malloc(sizeof(int)); // compiler error use of poisoned function malloc
*p=3;
std::cout<<*p<<'\n';
free(p);
}
我发现这种技术对于防止误用 C++ 中的保留字非常有用。
例如:
#include "test.h" // contains definition of some class T
#pragma GCC poison private
#define private public // oops compiler error use of poisoned identifier private in macro
int main()
{
// Instantiate T & use it members
}
这也可以在 C 中使用,以防止使用 C++ 关键字,因为 C++ 比 C 有更多关键字,并且在 C 中使用 C++ 特定关键字作为标识符是完全有效的。
例如(参见现场演示here)
#include <stdio.h>
#pragma GCC poison new
int main(void)
{
int new=5; // oops compiler error use of poisoned identifer new.
printf("%d",new);
}
但是要使用这种中毒,我们需要使用实现定义的 pragma 指令。幸运的是,由 clang & 识别的 GCC 编译指示也能很好地工作。但是如果我有 VC++ 编译器(Microsoft Visual studio),则需要哪个编译指示。如何在VC++编译器中做到这一点?
MSVC++ 有两种方法可以做到这一点。要获取您要使用的 GCC 版本#pragma 已弃用。这会产生警告 C4995,您可以使用 /WX 将其转换为错误。
然而,这会毒害具有您指定的名称的任何标识符,它的选择性不足以防止对恰好具有相同标识符名称的 C++ 成员发出警告。例如,您不能使用它来弃用特定的函数重载。通过第二种方式解决,__declspec(已弃用).
一般来说,您更喜欢后者以避免意外匹配。但请注意,它存在先有鸡还是先有蛋的问题,您只能弃用编译器知道的函数。比如说,强制您 #include 一个您根本不想使用的标头。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)