警告:施放需要对齐

我最近在这个平台上工作,其中一个遗留的代码库发布了大量的“强制增加对齐到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

上一篇: Warning: cast increases required alignment

下一篇: How do I use boost options