Странное определение в препроцессоре C++
Я сталкивался с этим
#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; }
и все понятно, кроме слова "C##_", что это значит?
6 ответов
Это значит "склеить" вместе, так c
а также _
получить "склеены", чтобы сформировать c_
, Это склеивание происходит после замены аргумента в макросе. Смотрите мой пример:
#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;
}
Это называется оператором вставки токена. Пример:
// preprocessor_token_pasting.cpp
#include <stdio.h>
#define paster( n ) printf( "token" #n " = %d", token##n )
int token9 = 9;
int main()
{
paster(9);
}
Выход
token9 = 9
После препроцессора ваш макрос будет расширен как:
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; }
Директива ## объединяет значение c, которое вы передаете как параметр макроса в _
Это объединение, которое добавляет подчеркивание к имени, переданному как c
, Поэтому, когда вы используете
DsHook(a,b,Something)
эта часть превращается в
if (!Something_)
Простой:
#define Check(a) if(c##x == 0) { }
На сайте звонка:
int varx; // Note the x
Check(var);
Будет расширяться как:
if(varx == 0) { }
Он называется объединением токенов и используется для объединения токенов во время предварительной обработки. Например, следующий код выведет значения значений 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;
}
Выход:
c=3 c_ = 0 and c_spam = 4