[英]C - alignas not giving expected result
C11中的Alignas
無法正常工作。 這是我的代碼:
#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));
}
輸出:
2, 2
4, 4
4, 4
4, 8
4, 8
4, 8
我期望所有這些結構的大小都相同。 為什么struct A
與struct B
大小不同? 我是否誤解了alignas
工作原理?
假設int16_t
需要2字節對齊,而int32_t
需要4字節對齊。
struct A
{
alignas(int32_t) int16_t a;
int16_t b;
};
它的自然布局是a
2個字節, b
的2個字節和整個結構的2個字節的對齊方式。
但是alignas(int32_t)
引入了其他限制: a
必須在4字節邊界上對齊。 這迫使整個結構在4字節邊界上對齊。 但大小a
是仍然僅有2個字節,所以b
可以隨后立即被置於與沒有填充,一個第(4n + 2)字節的邊界上。 b
2個字節之后,我們在4n + 4上,即再次在4字節邊界上。 這意味着我們在b
之后不需要填充:我們可以立即啟動該結構的另一個實例。
總而言之,我們有一個沒有填充的結構( sizeof (struct A)
是其成員大小之和4)和其第一個成員對齊的總和4。
struct B
{
int16_t a;
alignas(int32_t) int16_t b;
};
這里的情況有所不同: a
本身僅強制2字節對齊。 但是現在b
必須在4字節邊界上對齊,因此整個結構必須在4字節邊界上對齊,並且在a
之后插入2個字節的填充。 到目前為止,我們有2個字節用於a
,2個字節的填充,2個字節的b
,這使我們着陸在(4n + 6)(即4n + 2)字節邊界上。 我們需要達到開始的狀態,因此在b
之后插入另外2個字節的填充,以確保我們在4個字節的邊界上結束。
總而言之,我們最終得到2 + 2字節的填充和2 + 2字節的內容,大小為8。
您已指定B
的b
元素在4字節邊界上對齊。 由於a
只需要2個字節,這導致2個字節的填充之間a
和b
,和另一2個字節后b
使結構作為一個整體的4個字節的倍數。
對於A
,只有a
具有4個字節的對齊方式(通過在結構的開頭進行對齊)。 b
沒有額外的對齊要求,因此緊接也沒有填充,並且最后也不需要填充。
它們不同的原因是
sizeof給出存儲其類型或實例所需的實際大小(以字節為單位)。
alignof為您提供最大元素所需的字節對齊方式。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.