如何访问与宏同名的结构体成员?
结构体成员与宏同名时的访问方案
当结构体成员与宏同名时,直接通过.或->访问会触发预处理阶段的宏替换,导致编译失败(比如示例中t.foo会被替换为t.bar)。以下是无需取消宏定义的访问方案:
跨平台标准C方案
利用标准库的offsetof宏(定义在<stddef.h>中),通过计算成员偏移量来定位并访问目标成员:
#include <stddef.h> struct test { int foo; }; #define foo bar int main(int argc, char *argv[]) { struct test t; // 计算foo成员的偏移量,通过指针操作赋值 *(int *)((char *)&t + offsetof(struct test, foo)) = 5; return 0; }
原理:offsetof(struct test, foo)在编译期计算foo成员相对于结构体起始地址的偏移量,由于offsetof的参数在预处理阶段不会被宏替换(宏参数的特殊处理逻辑),因此能正确获取目标成员的位置。
GCC专属方案
方案1:使用__typeof__扩展
借助GCC的__typeof__编译期类型查询特性,绕过宏替换:
struct test { int foo; }; #define foo bar int main(int argc, char *argv[]) { struct test t; __typeof__(t) *pt = &t; pt->foo = 5; // 此处foo不会被宏替换 return 0; }
方案2:强制类型转换后访问
直接通过结构体类型的指针强制转换,也能绕过宏替换:
struct test { int foo; }; #define foo bar int main(int argc, char *argv[]) { struct test t; ((struct test *)&t)->foo = 5; return 0; }
原理:GCC在处理结构体类型限定的成员访问时,会优先识别为结构体成员,不会触发预处理阶段的宏替换。
内容的提问来源于stack exchange,提问作者Andreas
相关产品推荐
相关产品推荐

