我有一个结构,不想隐式填充。
#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.
这给了我一个我不想要的警告。
如果添加了隐式填充,但如果末尾缺少填充以对齐整个结构,我怎么会收到警告或编译时错误?我对使用它不感兴趣在一个数组中。或者这是一个冒险和粗心的事情允许吗?我确实需要正确对齐结构的实例。
是否有可以达到相同效果的属性或修饰符?
最佳答案
你可以这样做:
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
您将使用相同的方法:将所有字段的大小加起来直到最后一个,并检查最后一个字段的偏移量是否相同。
关于c++ - 我必须关心 C++ 结构末尾的填充吗?我保证我不会在数组中使用它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40078225/