Alignas在C11没有像我期待的那样工作.这是我的代码:
#include <inttypes.h>
#include <stdalign.h>
#include <stdio.h>
struct A
{
alignas(int32_t) int16_t a;
int16_t b;
};
struct B
{
int16_t a;
alignas(int32_t) int16_t b;
};
struct C
{
int16_t a;
int32_t b;
};
struct D
{
int32_t a;
int16_t b;
};
int main(void)
{
printf("%zu, %zu\n", alignof(int16_t), sizeof(int16_t));
printf("%zu, %zu\n", alignof(int32_t), sizeof(int32_t));
printf("%zu, %zu\n", alignof(struct A), sizeof(struct A));
printf("%zu, %zu\n", alignof(struct B), sizeof(struct B));
printf("%zu, %zu\n", alignof(struct C), sizeof(struct C));
printf("%zu, %zu\n", alignof(struct D), sizeof(struct D));
}
Run Code Online (Sandbox Code Playgroud)
输出:
2, 2
4, 4
4, 4
4, 8
4, 8
4, 8
Run Code Online (Sandbox Code Playgroud)
我预计所有这些结构的大小都是一样的.为什么struct A尺寸不一样struct B?我误解了怎么alignas运作?
假设int16_t需要2字节对齐并且int32_t需要4字节对齐.
struct A
{
alignas(int32_t) int16_t a;
int16_t b;
};
Run Code Online (Sandbox Code Playgroud)
这个的自然布局是2个字节a,2个字节b,以及整个结构的2字节对齐.
但是alignas(int32_t)引入了额外的约束:a必须在4字节边界上对齐.这会强制整个结构在4字节边界上对齐.但是大小a仍然只是2个字节,因此b可以在(4n + 2)字节边界上立即放置,没有填充.在2个字节后,b我们在4n + 4上,即再次在4字节边界上.这意味着我们之后不需要填充b:我们可以立即启动结构的另一个实例.
总而言之,我们有一个没有填充的结构(sizeof (struct A)是其成员大小的总和,4)和第一个成员的对齐,4.
struct B
{
int16_t a;
alignas(int32_t) int16_t b;
};
Run Code Online (Sandbox Code Playgroud)
这种情况不同:a它本身只强制2字节对齐.但是现在b必须在4字节边界上对齐,因此整个结构必须在4字节边界上对齐,然后插入2字节的填充a.到目前为止,我们有2个字节a,2个字节的填充,2个字节b,它们将我们置于(4n + 6)(即4n + 2)字节边界.我们需要达到我们开始的状态,然后插入另外2个字节的填充b以确保我们以4字节边界结束.
总而言之,我们最终得到2 + 2字节的填充和2 + 2字节的内容,大小为8.
| 归档时间: |
|
| 查看次数: |
157 次 |
| 最近记录: |