據我所知,結構的大小取決于使用的編譯器,編譯器可能會為對齊要求添加填充。
在 64 位系統上。我測驗了 2 個示例:
示例 1:
struct
{
uint8 a;
uint32 b;
uint8 c;
}ABC;
size of(uint8 a) == 1 bytes 3 bytes padding
size of(uint32 b) == 4 bytes 0 padding
size of(uint8 c) == 1 bytes 3 padding
==> So, size of(ABC) = 12 bytes.
示例 2:
struct
{
uint8 a;
uint16 b;
uint8 c;
}ABC;
size of(uint8 a) == 1 bytes 1 bytes padding
size of(uint16 b) == 2 bytes 0 padding
size of(uint8 c) == 1 bytes 3 padding
==> So, I assumed size of(ABC) = 8 bytes.
但是,編譯器回傳 (ABC) = 6 個位元組的大小。
為什么示例 2 中的 (ABC) = 6 個位元組而不是我理解的 8 個位元組?
uj5u.com熱心網友回復:
編譯器嘗試對齊結構型別的物件,以使具有最嚴格對齊的資料成員可以適當地對齊。
在這個結構宣告中
struct
{
uint8 a;
uint16 b;
uint8 c;
}ABC;
具有最嚴格對齊的資料成員是資料成員b。它的地址應該對齊兩個位元組。所以資料成員a被填充了一個位元組。為了使結構物件的地址對齊 2 個位元組,資料成員c也用 1 個位元組填充。
uj5u.com熱心網友回復:
編譯器可能會為對齊要求添加填充。請注意,這不僅適用于結構欄位之間的填充,還可能適用于結構的末尾(這樣結構型別的陣列將使每個元素正確對齊)。
例如:
struct foo_t {
int x;
char c;
};
即使 c 欄位不需要填充,結構通常也會有 sizeof(struct foo_t) == 8 (在 32 位系統上 - 而不是具有 32 位 int 型別的系統),因為需要c 欄位后的 3 個位元組的填充。
請注意,系統(如 x86 或 Cortex M3)可能不需要填充,但出于性能原因,編譯器可能仍會添加它。
uj5u.com熱心網友回復:
size of(uint8 c) == 1 bytes 3 padding`
==> So, I assumed size of(ABC) = 8 bytes.
沒有理由添加三個位元組的填充。因為uint8(可能是真的uint8_t或等價的)的對齊要求是一個位元組,而uint16(可能是真的uint16_t或等價的)的對齊要求是兩個位元組,所以完整結構的對齊要求是其中的最大值,即兩個位元組。使用一個位元組用于uint8 a,一個位元組用于填充以進行uint16 b對齊,兩個位元組用于uint16 b,一個位元組用于uint8 c,到該點的結構大小為五個位元組。然后只需要一個位元組就可以使它成為其對齊要求的倍數,所以總共是六個位元組。
通常用于布局結構的規則是:
- 結構中的每個成員都有一些大小s和一些對齊要求a。
- 編譯器從大小S設定為零和對齊要求A設定為一(位元組)開始。
- 編譯器按順序處理結構中的每個成員:
- 考慮成員的對齊要求a。如果S當前不是 a 的倍數,則向S添加足夠的位元組,使其成為 a 的倍數。這決定了會員的去向;它將從結構的開頭開始偏移S(對于S的當前值)。
- 將A設定為A和a 的最小公倍數1。
- 將s添加到S,為成員留出空間。
- 當為每個成員完成上述程序時,考慮結構的對齊要求A。如果S當前不是A的倍數,則將其添加到S使其成為A的倍數。
完成上述操作后,結構的大小就是S的值。
此外:
- 如果任何成員是一個陣列,它的大小就是元素個數乘以每個元素的大小,它的對齊要求就是一個元素的對齊要求。
- 如果任何成員是結構,則其大小和對齊要求如上計算。
- 如果任何成員是聯合體,則其大小是其最大成員的大小加上剛好足以使其成為所有成員對齊的最小公倍數1的倍數。
對于基本型別(int、double等),對齊要求是實作定義的,通常主要由硬體決定。在許多處理器上,當資料具有一定的對齊方式時(通常當其在記憶體中的地址是其大小的倍數時)加載和存盤資料會更快。除此之外,上述規則主要來自邏輯。他們將每個成員放置在必須滿足對齊要求的位置,而不會占用不必要的空間。
腳注
1對于一般情況,我將其表述為使用對齊要求的最小公倍數。但是,由于對齊要求始終是 2 的冪,因此任何一組對齊要求的最小公倍數是其中最大的。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/487782.html
