You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何编写#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; }
    

原理说明

  1. CONCAT宏通过可变参数接收类型的各个部分(用逗号分隔),SELECT_CONCAT会根据参数的数量自动选择CONCAT3、CONCAT2或identity宏,完成令牌的连接。
  2. DEFINE_FUNCTION宏利用CONCAT生成无空格的标识符作为函数名后缀,同时保留原类型的空格格式用于函数参数的类型声明。

内容的提问来源于stack exchange,提问作者user1806687

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 21:17:51