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

如何访问与宏同名的结构体成员?

结构体成员与宏同名时的访问方案

当结构体成员与宏同名时,直接通过.或->访问会触发预处理阶段的宏替换,导致编译失败(比如示例中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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 18:32:42