Weird define in C++ preprocessor
I've come across this
#define DsHook(a,b,c) if (!c##_) { INT_PTR* p=b+*(INT_PTR**)a; VirtualProtect(&c##_,4,PAGE_EXECUTE_READWRITE,&no); *(INT_PTR*)&c##_=*p; VirtualProtect(p,4,PAGE_EXECUTE_READWRITE,&no); *p=(INT_PTR)c; }
and everything is clear except the "c##_" word, what does that 开发者_开发百科mean?
It means to "glue" together, so c
and _
get "glued together" to form c_
. This glueing happens after argument replacement in the macro. See my example:
#define glue(a,b) a##_##b
const char *hello_world = "Hello, World!";
int main(int arg, char *argv[]) {
printf("%s\n", glue(hello,world)); // prints Hello, World!
return 0;
}
It is called a token-pasting operator. Example:
// preprocessor_token_pasting.cpp
#include <stdio.h>
#define paster( n ) printf( "token" #n " = %d", token##n )
int token9 = 9;
int main()
{
paster(9);
}
Output
token9 = 9
That's concatenation that appends an underscore to the name passed as c
. So when you use
DsHook(a,b,Something)
that part turns into
if (!Something_)
After the preprocessor, your macro will be expanded as:
if (!c_) { INT_PTR* p=b+*(INT_PTR**)a; VirtualProtect(&c_,4,PAGE_EXECUTE_READWRITE,&no); *(INT_PTR*)&c_=*p; VirtualProtect(p,4,PAGE_EXECUTE_READWRITE,&no); *p=(INT_PTR)c; }
The ## directive concatenates the value of c which you pass as a macro parameter to _
Simple one:
#define Check(a) if(c##x == 0) { }
At call site:
int varx; // Note the x
Check(var);
Would expand as:
if(varx == 0) { }
It is called Token Concatenation and it is used to concatenate tokens during the preprocessing For example the following code will print out the values of the values of c, c_, c_spam:
#include<stdio.h>
#define DsHook(a,b,c) if (!c##_) \
{printf("c=%d c_ = %d and c_spam = %d\n",\
c, c##_,c##_spam);}
int main(){
int a,b,c=3;
int c_ = 0, c_spam = 4;
DsHook(a,b,c);
return 0;
}
Output:
c=3 c_ = 0 and c_spam = 4
精彩评论