预处理程序宏转换

时间:2019-01-10 22:39:14

标签: c c-preprocessor preprocessor

在.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 :(得分: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