如何在 VC++ 中给一个标识符下毒?
How to poison an identifier in VC++?
函数投毒 是 C++ 中非常有用的技术。
一般是指使某个功能无法使用,例如如果你想禁止在程序中使用动态分配,你可以 "poison" malloc 函数,这样它就不能使用了。 'Poisoning' 标识符意味着在 'poisoning' 之后对标识符的任何引用都是硬编译器错误
例如(查看现场演示 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 pragma 也运行良好。但是如果我有 VC++ 编译器(Microsoft Visual studio),则需要哪个 pragma。如何在 VC++ 编译器中执行此操作?
MSVC++ 有两种方法可以做到这一点。要获取 GCC 版本,您将使用 #pragma deprecated。这会产生警告 C4995,您可以使用 /WX 将其转换为错误。
尽管这会毒化任何具有您指定名称的标识符,但它的选择性不足以防止对碰巧具有相同标识符名称的 C++ 成员发出警告。例如,您不能使用它来弃用特定的函数重载。通过第二种方式解决,__declspec(deprecated).
一般来说,您更喜欢后者以避免意外匹配。但请注意它有一个 chicken-and-egg 问题,您只能弃用编译器知道的函数。强迫你,比如说,#include 一个你根本不想使用的 header。
函数投毒 是 C++ 中非常有用的技术。
一般是指使某个功能无法使用,例如如果你想禁止在程序中使用动态分配,你可以 "poison" malloc 函数,这样它就不能使用了。 'Poisoning' 标识符意味着在 'poisoning' 之后对标识符的任何引用都是硬编译器错误
例如(查看现场演示 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 pragma 也运行良好。但是如果我有 VC++ 编译器(Microsoft Visual studio),则需要哪个 pragma。如何在 VC++ 编译器中执行此操作?
MSVC++ 有两种方法可以做到这一点。要获取 GCC 版本,您将使用 #pragma deprecated。这会产生警告 C4995,您可以使用 /WX 将其转换为错误。
尽管这会毒化任何具有您指定名称的标识符,但它的选择性不足以防止对碰巧具有相同标识符名称的 C++ 成员发出警告。例如,您不能使用它来弃用特定的函数重载。通过第二种方式解决,__declspec(deprecated).
一般来说,您更喜欢后者以避免意外匹配。但请注意它有一个 chicken-and-egg 问题,您只能弃用编译器知道的函数。强迫你,比如说,#include 一个你根本不想使用的 header。