宏如何根据传入的参数访问不同的结构体成员?
下面的代码中,我有两种结构体类型,它们的成员名各不相同。
我想在一个宏(或函数)中使用它们,并通过区分“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导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。