如何编写#define CONCATENATE(x)宏以生成可用于函数命名的单一令牌?
C宏实现带空格类型名的单一令牌合并
要实现将带空格的类型名(比如unsigned int、long long int)合并为无空格的单一标识符(用于生成函数名),标准C预处理器无法直接处理带空格的单个宏参数(因为空格分隔的是独立令牌),我们可以通过将类型的各部分用逗号分隔传入宏的方式,配合可变参数宏完成令牌连接。
实现代码
// 辅助宏:连接2个令牌 #define CONCAT2(a, b) a##b // 辅助宏:连接3个令牌 #define CONCAT3(a, b, c) a##b##c // 根据参数数量自动选择对应的连接宏 #define SELECT_CONCAT(_1, _2, _3, FUNC, ...) FUNC #define CONCAT(...) SELECT_CONCAT(__VA_ARGS__, CONCAT3, CONCAT2, identity)(__VA_ARGS__) // 处理单个参数的情况(直接返回参数本身) #define identity(x) x // 生成类型对应的缓冲区操作函数 #define DEFINE_FUNCTION(...) \ void Buffer_##CONCAT(__VA_ARGS__)##_Add(size_t idx, __VA_ARGS__ *buffer, __VA_ARGS__ data) \ { \ buffer[idx] = data; \ }
使用示例
针对单单词类型:
DEFINE_FUNCTION(int);展开后生成:
void Buffer_int_Add(size_t idx, int *buffer, int data) { buffer[idx] = data; }针对双单词类型:
DEFINE_FUNCTION(unsigned, int);展开后生成:
void Buffer_unsignedint_Add(size_t idx, unsigned int *buffer, unsigned int data) { buffer[idx] = data; }针对三单词类型:
DEFINE_FUNCTION(long, long, int);展开后生成:
void Buffer_longlongint_Add(size_t idx, long long int *buffer, long long int data) { buffer[idx] = data; }
原理说明
CONCAT宏通过可变参数接收类型的各个部分(用逗号分隔),SELECT_CONCAT会根据参数的数量自动选择CONCAT3、CONCAT2或identity宏,完成令牌的连接。DEFINE_FUNCTION宏利用CONCAT生成无空格的标识符作为函数名后缀,同时保留原类型的空格格式用于函数参数的类型声明。
内容的提问来源于stack exchange,提问作者user1806687
相关产品推荐
相关产品推荐

