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

通过显式算术计算结构体元素指针是否符合ISO C标准?

显式计算结构体元素指针的合法性与ISO C标准符合性

问题

显式通过算术计算结构体元素指针的方式是否合法?以下程序是否符合ISO C标准(而非仅在特定编译器上可运行)?

struct foo {
  int a, b, c;
};

int f(struct foo *p) {
  // should return p->c
  char *q = ((char *)p) + 2 * sizeof(int);
  return *((int *)q);
}

初步分析

该程序似乎符合部分指针合法使用规则:

  • 加载的值与地址存储的类型一致;
  • 计算得到的指针的provenance合法,由有效指针偏移得到且仍在原存储实例内;
  • 结构体内部无类型混合,不会产生导致元素偏移不可预测的填充。

结论与标准依据

这个程序完全符合ISO C标准,具体依据如下:

  1. 结构体成员布局的确定性:
    ISO C标准规定,结构体成员按声明顺序存储,且成员的偏移量必须满足自身类型的对齐要求。对于连续的同类型成员(如本例中的int a, b, c),由于int的大小等于其对齐要求(绝大多数平台均如此,且标准允许的实现也会保证这一点),成员之间不会存在填充。因此c相对于结构体起始地址的偏移量确实是2 * sizeof(int),显式计算的偏移是准确的。

  2. 指针转换与算术的合法性:
    标准允许将任意对象指针转换为字符类型指针(char*/unsigned char*/signed char*),且字符指针的算术运算可以用来遍历对象的字节。本例中从struct foo*转换为char*后进行偏移,得到的指针仍指向原结构体对象的内部,指针的来源(provenance)合法。

  3. 指针转回与解引用的合法性:
    将字符指针转回int*时,由于c的地址满足int类型的对齐要求(结构体起始地址对齐,偏移量是sizeof(int)的整数倍),转换后的指针是合法对齐的。后续解引用该指针时,访问的对象类型与指针类型一致,符合标准对指针解引用的要求。

注意事项

如果结构体成员类型不同,或成员之间因对齐要求存在填充,这种显式计算偏移的方式会导致未定义行为——但本例的结构体不存在这类问题,因此可以安全使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 06:25:29