Правильное использование смещения макроса - PullRequest
1 голос
/ 03 марта 2012

Я пытаюсь работать с макросом 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)
  • Есть ли лучший способ сделать то, что я делаю?(Мне нужно сделать это, чтобы избежать хранения x и y для каждого MapBlock, но иметь возможность доступа к ним через блок, не зная связанных MapTile)
  • можно ли избежать приведения к u8 при вычитании смещения?Наверное, нет, но я просто хотел быть уверен ..

Спасибо

1 Ответ

0 голосов
/ 15 марта 2012

На самом деле все, что мне казалось, работало очень хорошо с моим решением. Оптимизация, предложенная в комментариях (с использованием block - 1), тоже сработала, поэтому не стесняйтесь использовать мой пример, если у вас есть похожая проблема!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...