Правильное использование смещения макроса
Я пытаюсь работать с 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
но иметь возможность доступа к ним через блок, не зная связанныхMapTile
) - могу ли я избежать броска на
u8
при вычитании смещения? Я думаю, нет, но я просто хотел быть уверен..
Спасибо
1 ответ
Решение
На самом деле все, что мне казалось, работало очень хорошо с моим решением. Оптимизации, предложенные в комментариях (используя block - 1
) тоже работал, так что не стесняйтесь использовать мой пример, если у вас есть похожая проблема!