宏如何根据传入的参数访问不同的结构体成员?

编程语言 2026-07-11

下面的代码中,我有两种结构体类型,它们的成员名各不相同。
我想在一个宏(或函数)中使用它们,并通过区分“ID”来访问它们的成员。
然而,如果把它写成一个宏,它会报告以下错误。
我猜宏是在预处理阶段展开的,在汇编层面这段代码可能以某种出乎意料的方式写入。
在C 语言中有没有办法写出类似的实现?

struct s1 {
    int x;
};

struct s2 {
    int y;
};

#define MY_MACRO(ID, TYPE) do {  \
    TYPE new;                    \
    if(ID == 1) {                \
        new.x = 10;              \
    } else {                     \
        new.y = 20;              \
    }                            \
} while(0);

int main()
{
    MY_MACRO(1, struct s1);
    MY_MACRO(2, struct s2);

    return 0;
}
$ gcc test2.c 
test2.c: In function ‘main’:
test2.c:18:12: error: ‘struct s1’ has no member named ‘y’
   18 |         new.y = 20;        \
      |            ^
test2.c:24:5: note: in expansion of macro ‘MY_MACRO’
   24 |     MY_MACRO(1, struct s1);
      |     ^~~~~~~~
test2.c:16:12: error: ‘struct s2’ has no member named ‘x’
   16 |         new.x = 10;  \
      |            ^
test2.c:25:5: note: in expansion of macro ‘MY_MACRO’
   25 |     MY_MACRO(2, struct s2);

解决方案

#include <stdio.h>

struct s1 { int x; };
struct s2 { int y; };

#define MY_MACRO(val) _Generic((val),   \
    struct s1: handle_s1,               \
    struct s2: handle_s2                \
)(&(val))

void handle_s1(struct s1 *s) { s->x = 10; }
void handle_s2(struct s2 *s) { s->y = 20; }

int main() {
    struct s1 a;
    struct s2 b;
    MY_MACRO(a);
    MY_MACRO(b);
    printf("a.x = %d, b.y = %d\n", a.x, b.y);
}

_Generic 实现了 编译时类型分派——每个分支只针对匹配的类型进行编译,因此不会出现“缺少成员”的错误。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章