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

如何让C语言的_Generic宏支持传入类型名或值作为参数

实现方案

核心思路是利用typeof(C23纳入标准,此前为绝大多数C编译器支持的通用扩展)的特性:typeof本身就支持接受类型名或表达式作为参数,返回对应的类型。我们只需要用typeof(x)统一生成对应类型的复合字面量作为_Generic的选择器,即可完美兼容两种输入场景,同时覆盖算术类型、自定义结构体等所有合法C类型。

示例实现

#include <stdio.h>

// 自定义结构体测试用
struct Foo {
    int val;
};

#define F(x) _Generic((typeof(x)){0}, \
    int: 1, \
    long: 2, \
    struct Foo: 3 \
)

int main(void) {
    struct Foo f = {0};
    // 测试类型参数
    printf("%d\n", F(int)); // 输出1
    printf("%d\n", F(long)); // 输出2
    printf("%d\n", F(struct Foo)); // 输出3
    // 测试表达式参数
    printf("%d\n", F(100)); // 输出1
    printf("%d\n", F(100L)); // 输出2
    printf("%d\n", F(f)); // 输出3
    return 0;
}

原理解释

  1. 当传入参数为类型名时:typeof(x)直接返回该类型,构造复合字面量(类型){0}完全合法
  2. 当传入参数为表达式时:typeof(x)返回表达式的求值类型,同样可以构造合法的复合字面量
  3. 完全对齐sizeof的参数适配逻辑,没有原实现中算术类型不支持结构体、复合字面量不支持字面量值的缺陷

如果需要严格兼容纯C11标准(无typeof扩展),目前没有通用的语法技巧可以实现该需求,C标准中没有无需扩展就能同时区分/适配类型名和表达式作为宏参数的机制。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 11:15:08