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

非数组复合成员间的字节指针偏移计算是否有定义?

复合对象成员指针相减的行为疑问

我理解C++标准expr.add#4.2条款中,将+和-操作限制为指向同一数组元素的指针的原因,这在我之前关于偏移指针类的问题评论中已有解释。但类似操作也可在同一(嵌套)复合对象的成员间完成,不一定局限于数组。若此类偏移结果不确定,offsetof宏便失去意义。

以下是类比offsetof的示例:

#include <iostream>
#include <cstddef>

struct Inner
{
    int i1;
    float f;
    bool b;
    int i2;
};

struct Outer
{
    int i1;
    char c;
    int i2;
    Inner inner;
    double d;
};

int main(int argc, char* argv[])
{
    Outer outer;
    std::cout << "reinterpret_cast<std::byte*>(&outer.i2) - reinterpret_cast<std::byte*>(&outer.i1): "
              << reinterpret_cast<std::byte*>(&outer.i2) - reinterpret_cast<std::byte*>(&outer.i1) << std::endl;
    std::cout << "reinterpret_cast<std::byte*>(&outer.inner.i2) - reinterpret_cast<std::byte*>(&outer.i1): "
              << reinterpret_cast<std::byte*>(&outer.inner.i2) - reinterpret_cast<std::byte*>(&outer.i1) << std::endl;
    std::cout << "offsetof(Outer, i2) - offsetof(Outer, i1): " << offsetof(Outer, i2) - offsetof(Outer, i1) << std::endl;
    std::cout << "offsetof(Outer, inner) + offsetof(Inner, i2) - offsetof(Outer, i1): "
              << offsetof(Outer, inner) + offsetof(Inner, i2) - offsetof(Outer, i1) << std::endl;

    return 0;
}

运行结果:

reinterpret_cast<std::byte*>(&outer.i2) - reinterpret_cast<std::byte*>(&outer.i1): 8
reinterpret_cast<std::byte*>(&outer.inner.i2) - reinterpret_cast<std::byte*>(&outer.i1): 24
offsetof(Outer, i2) - offsetof(Outer, i1): 8
offsetof(Outer, inner) + offsetof(Inner, i2) - offsetof(Outer, i1): 24

所有涉及的指针目标都在outer对象内,但并非同一对象。这属于未定义行为吗?

(经评论后编辑:非字节指针在混合类型复合对象中会失效,且C++标准expr.add#4.2条款中的"假设"无法满足我的需求,感谢!)

支持其为定义行为的论据:

  • 指针转换为std::byte、char和unsigned char类型的操作在严格别名规则限制下是有定义的。
  • 指向外部复合对象的字节指针指向代表整个复合对象的字节数组A的第一个元素。
  • offsetof的语义要求所有复合成员在复合对象内有固定偏移。
  • 因此,所有转换为字节指针的复合成员指针也指向数组A的元素。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 20:00:02