我有一个结构,不需要隐式填充。
#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.
这给了我一个我不想要的警告。
如果添加了隐式填充,我怎么能得到警告或编译时错误,但是如果最后没有填充以对齐整个结构,则不会出现错误?我对此不感兴趣在数组中使用它。或者这是一个冒险和粗心的事情吗?我确实需要结构的实例正确对齐。
是否有可以达到同样效果的属性或修饰符?
答案 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
您使用相同的方法:将所有字段的大小相加到最后一个字段,并检查最后一个字段的偏移量是否相同。