我必须关心C ++结构末尾的填充吗?我保证我不会在阵列中使用它

时间:2016-10-17 03:49:55

标签: c++ g++ compiler-warnings clang++ memory-alignment

我有一个结构,不需要隐式填充

#include <cstdint>
struct foo
{
  uint8_t a;
  uint32_t b;
};
static_assert(sizeof(foo) == 8, "");

我打开 -Wpadded 警告。

> g++ test.cpp -c -Wpadded -std=c++14
test.cpp:5:12: warning: padding struct to align 'foo::b' [-Wpadded]
   uint32_t b;
            ^

> clang++ test.cpp -c -Wpadded -std=c++14
test.cpp:5:12: warning: padding struct 'foo' with 3 bytes to align 'b' [-Wpadded]
  uint32_t b;
           ^
1 warning generated.

那很棒,这就是我想要的。

我现在切换成员。我不在乎最后的填充以使结构正确对齐。我只是把尺寸缩小了。

#include <cstdint>
struct foo
{
  uint32_t b;
  uint8_t a;
};
static_assert(sizeof(foo) == 5, "");

> g++ test.cpp -c -Wpadded -std=c++14
test.cpp:2:8: warning: padding struct size to alignment boundary [-Wpadded]
 struct foo
        ^
test.cpp:7:1: error: static assertion failed:
 static_assert(sizeof(foo) == 5, "");
 ^

> clang++ test.cpp -c -Wpadded -std=c++14
test.cpp:2:8: warning: padding size of 'foo' with 3 bytes to alignment boundary [-Wpadded]
struct foo
       ^
test.cpp:7:1: error: static_assert failed ""
static_assert(sizeof(foo) == 5, "");
^             ~~~~~~~~~~~~~~~~
1 warning and 1 error generated.

这给了我一个我不想要的警告。

如果添加了隐式填充,我怎么能得到警告或编译时错误,但是如果最后没有填充以对齐整个结构,则不会出现错误?我对此不感兴趣在数组中使用它。或者这是一个冒险和粗心的事情吗?我确实需要结构的实例正确对齐。

是否有可以达到同样效果的属性或修饰符?

1 个答案:

答案 0 :(得分:0)

你可以这样做:

static_assert(offsetof(foo, b) == offsetof(foo, a) + sizeof(uint8_t), "");

当然,您需要在第一个成员之后为每个成员添加一个断言,或者更改上面的内容以包含所有字段,例如如果c是最后一个字段:

static_assert(offsetof(foo, c) == sizeof(uint8_t) + sizeof(uint32_t), "");

现在你可能想知道如何让它更自动化。你可以使用Boost.Fusion ......这是我问过的一个问题并按照以下方式回答:

Boost Fusion: validate adapted struct member ordering at compile time

您使用相同的方法:将所有字段的大小相加到最后一个字段,并检查最后一个字段的偏移量是否相同。