在.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”部分使我感到困惑...
答案 0 :(得分:4)
##
操作符是串联的,在这里使用是因为function_ptr
是有效的标识符,因此预处理器将不知道要替换其中的function
部分。那么,预处理的结果是:
extern "C" int coreclr_shutdown(void* hostHandle, unsigned int domainId);
typedef int (*coreclr_shutdown_ptr)(void* hostHandle, unsigned int domainId);
(为便于阅读,我对模空白进行了更改)
答案 1 :(得分:2)
有时,有些编译器选项允许您查看语句的预处理器输出。如果没有,总是存在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