Странное определение в препроцессоре C ++ - PullRequest
3 голосов
/ 17 августа 2011

Я сталкивался с этим

#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 ]

4 голосов
/ 17 августа 2011

Это означает «склеивать» вместе, поэтому 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;
}
3 голосов
/ 17 августа 2011

Он называется оператором вставки токена . Пример:

// 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
2 голосов
/ 17 августа 2011

После препроцессора ваш макрос будет расширен как:

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, которое вы передаете как параметр макроса, в _

2 голосов
/ 17 августа 2011

Это объединение, которое добавляет подчеркивание к имени, переданному как c.Поэтому, когда вы используете

DsHook(a,b,Something)

, эта часть превращается в

if (!Something_) 
1 голос
/ 17 августа 2011

Это называется объединением токенов и используется для объединения токенов во время предварительной обработки. Например, следующий код выведет значения значений 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
1 голос
/ 17 августа 2011

Простой:

#define Check(a) if(c##x == 0) { }

На сайте звонка:

int varx; // Note the x
Check(var);

будет расширяться как:

if(varx == 0) { }
...