正确使用offsetof宏

时间:2012-03-03 17:23:34

标签: c++ c pointers pointer-arithmetic offsetof

我正在尝试以下列方式使用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 == %p\n",tfb(&map[40][50].top),tfb(&map[40][50].middle),&map[40][50]);

现在真正的问题:

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

由于

1 个答案:

答案 0 :(得分:0)

事实上,对于我的解决方案,evertything似乎工作得很好。评论中建议的优化(使用block - 1)确实也有效,如果您遇到类似问题,请随意使用我的示例!