Препроцессор Макро Перевод - PullRequest
0 голосов
/ 11 января 2019

В исходном коде .NET Core CLR я нашел следующее определение макроса:

#define CORECLR_HOSTING_API(function, ...) \
  extern "C" int function(__VA_ARGS__); \
  typedef int (*function##_ptr)(__VA_ARGS__)

CORECLR_HOSTING_API(coreclr_shutdown,
            void* hostHandle,
            unsigned int domainId);

В комментариях говорится, что это определяет прототип функции и указатель на функцию. Может ли кто-нибудь «перевести», как будет выглядеть немакрос версия? То есть как бы это выглядело, если бы НЕ было обернуто в макрос? Часть "* function ## _ ptr" сбивает меня с толку ...

Ответы [ 2 ]

0 голосов
/ 11 января 2019

Иногда встречаются опции компилятора, которые позволяют видеть вывод пропроцессора операторов. Если нет, то всегда есть godbolt , в котором вы можете использовать опцию -E с gcc компилятором, чтобы увидеть (новая строка добавлена ​​мной):

extern "C" int coreclr_shutdown(void* hostHandle, unsigned int domainId); 
typedef int (*coreclr_shutdown_ptr)(void* hostHandle, unsigned int domainId)

## в раскрытии макроса означает конкатенацию. Таким образом, function ## _ptr означает объединение строки за function (это аргумент макроса) со строкой (литерал) _ptr. Как правило, например:

#define CONCAT(a,b) a ## b
CONCAT(abc, def) // will be translated by preprocessor into abcdef
0 голосов
/ 11 января 2019

Оператор ## является конкатенацией, здесь используется, потому что function_ptr является допустимым идентификатором, поэтому препроцессор не будет знать, чтобы заменить его часть function. Таким образом, результат предварительной обработки:

extern "C" int coreclr_shutdown(void* hostHandle, unsigned int domainId);
typedef int (*coreclr_shutdown_ptr)(void* hostHandle, unsigned int domainId);

(по модулю изменения пробелов, которые я сделал для удобства чтения)

...