如何在VC++中毒害标识符

How to poison an identifier in VC++?

本文关键字:标识符 中毒 VC++      更新时间:2023-10-16

函数中毒是C++中非常有用的技术。

通常,它指的是使函数不可用,例如,如果你想禁止在程序中使用动态分配,你可以"毒害"malloc函数,使其无法使用"中毒"标识符意味着在"中毒"之后对该标识符的任何引用都是硬编译错误

例如(请参阅此处的实时演示)

#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.中的标识符是完全有效的

例如(请参阅此处的实时演示)

#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指令。幸运的是,GCC实用主义者通过clang&也很好用。但是,如果我有VC++编译器(Microsoft Visual studio),则需要哪个杂注。如何在VC++编译器中做到这一点?

MSVC++有两种方法可以做到这一点。要获得GCC版本,您可以使用#pragma弃用。这会产生警告C4995,您可以使用/WX将其转化为错误。

然而,这会毒害具有指定名称的任何标识符,它的选择性不足,无法防止对碰巧具有相同标识符名称的C++成员发出警告。例如,你不能用它来贬低特定的函数重载。通过第二种方法__declspec(已弃用)解决。

一般来说,为了避免意外匹配,你更喜欢后者。但要注意,它有一个鸡和蛋的问题,你只能弃用编译器知道的函数。强迫你,比如说,#包含一个你根本不想使用的头。