Function poisoning is very useful technique in C++.
In general it refers to making a function unusable, e.g. if you want to ban the use of dynamic allocation in a program you could "poison" the malloc function so it can't be used. 'Poisoning' an identifier means that any reference to the identifier after the 'poisoning' is a hard compiler error
For example (See live demo 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);
}
I found this technique very useful to prevent misuse of reserved words in C++.
For example:
#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
}
This can also be used in C to prevent the use of C++ keywords because C++ has many keywords than C & it is perfectly valid to use C++ specific keywords as an identifier in C.
For example (See live demo 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);
}
But to use this poisoning we need to use the pragma directive which is implementation defined. Fortunately the GCC pragma reconginized by clang & also works nicely. But which pragma is needed If I 've VC++ compiler (Microsoft Visual studio). How to do this in VC++ compiler?
MSVC++ has two ways to do this. To get the GCC version you'd use #pragma deprecated. That produces warning C4995, you can turn that into an error with /WX.
That however poisons any identifier with the name you specified, it isn't selective enough to prevent warnings on C++ members that happen to have the same identifier name. You couldn't use it to deprecate a specific function overload for example. Solved by the second way, __declspec(deprecated).
In general you'd prefer the latter to avoid accidental matches. But do beware that it has a chicken-and-egg problem, you can only deprecate a function that the compiler knows about. Forcing you to, say, #include a header that you don't want to use at all.
来源:https://stackoverflow.com/questions/34118209/how-to-poison-an-identifier-in-vc