宏偏移量的正确用法

Correct usage of offsetof macro

本文关键字:用法 偏移量      更新时间:2023-10-16

我正在尝试以以下方式使用offsetof宏:

typedef unsigned char u8;
typedef unsigned short u16;
struct MapBlock
{
  u16 type : 10;
  u8 variant : 3;
  bool isTop : 1;
};
struct MapTile
{
  struct MapBlock top, middle;
  u16 x;
  u8 y;
};
MapTile *tfb(struct MapBlock *block)
{
  if (block->isTop)
    return (MapTile*)block;
  else
    return (MapTile*)((u8*)block - offsetof(struct MapTile, middle));
}

它似乎可以与这个简单的测试用例一起工作:

for (int i = 0; i < width; ++i)
  for (int j = 0; j < height; ++j)
  {
    map[i][j].x = i;
    map[i][j].y = j;
    map[i][j].top.isTop = true;
    map[i][j].middle.isTop = false;
  }
printf("%p == %p == %pn",tfb(&map[40][50].top),tfb(&map[40][50].middle),&map[40][50]);

现在真正的问题是:

  • 它安全吗?(假设使用g++
  • 它能与任何标准优化一起工作吗?(主要为-O2
  • 有更好的方法来做我正在做的事情吗?(我需要这样做,以避免为每个MapBlock存储xy,但能够在不知道相关MapTile的情况下通过块访问它们)
  • 在减去偏移量时,我可以避免转换为u8吗?我想没有,但我只是想确定一下

感谢

实际上,我的解决方案似乎一切都很好。评论中建议的优化(使用block - 1)也起到了作用,所以如果您有类似的问题,请随意使用我的示例!