警告:施放需要对齐
我最近在这个平台上工作,其中一个遗留的代码库发布了大量的“强制增加对齐到N”的警告,其中N是演员目标的大小。
struct Message
{
int32_t id;
int32_t type;
int8_t data[16];
};
int32_t GetMessageInt(const Message& m)
{
return *reinterpret_cast<int32_t*>(&data[0]);
}
希望这是显而易见的是一个“真实”的实施将是一个有点复杂,但基本的一点是,我有数据从什么地方来的,我知道,它的排列(因为我需要的ID和类型对齐),和但我得到的消息是演员阵容正在增加对齐,在例子中,为4。
现在我知道,我可以抑制警告带参数的编译器,我知道我能投,括号内的位为void *第一,但我真的不想去通过代码的每一位需要这(有很多是因为我们从磁盘加载了很多数据,并且这些数据以字符缓冲区的形式出现,以便我们可以轻松地进行指针提升),但任何人都可以给我关于此问题的其他想法吗? 我的意思是,对我来说,这似乎是一个非常重要和普遍的选择,你不会想警告,如果实际存在错误的可能性,那么压制警告是无济于事的。 最后,不能让编译器知道所讨论的对象是如何在结构中实际对齐的,所以它应该能够不担心该特定对象上的对齐,除非它碰到了一两个字节?
一种可能的选择可能是:
int32_t GetMessageInt(const Message& m)
{
int32_t value;
memcpy(&value, &(data[0]), sizeof(int32_t));
return value;
}
对于x86体系结构,对齐不会太重要,它更像是一个性能问题,与您提供的代码无关。 对于其他体系结构(例如MIPS),未对齐的访问会导致CPU异常。
好的,这是另一种选择:
struct Message
{
int32_t id;
int32_t type;
union
{
int8_t data[16];
int32_t data_as_int32[16 * sizeof(int8_t) / sizeof(int32_t)];
// Others as required
};
};
int32_t GetMessageInt(const Message& m)
{
return m.data_as_int32[0];
}
以上是包含来自cpstubing06
的建议的变体:
template <size_t N>
struct Message
{
int32_t id;
int32_t type;
union
{
int8_t data[N];
int32_t data_as_int32[N * sizeof(int8_t) / sizeof(int32_t)];
// Others as required
};
static_assert((N * sizeof(int8_t) % sizeof(int32_t)) == 0,
"N is not a multiple of sizeof(int32_t)");
};
int32_t GetMessageInt(const Message<16>& m)
{
return m.data_as_int32[0];
}
// Runtime size checks
template <size_t N>
void CheckSize()
{
assert(sizeof(Message<N>) == N * sizeof(int8_t) + 2 * sizeof(int32_t));
}
void CheckSizes()
{
CheckSize<8>();
CheckSize<16>();
// Others as required
}
链接地址: http://www.djcxy.com/p/45549.html