Странное определение в препроцессоре 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
Другие вопросы по тегам