簡體   English   中英

嵌套結構填充 - C - 64位 - linux

[英]Nested structure padding - C - 64 bit - linux

我在C中有以下嵌套結構(64位)

    typedef struct {
        int a;
        int b;
        int c;
        struct {
            int ab;
            long bc;
        }
        int d;
    } Test;

I see that,
a = 4 bytes
b = 4 bytes
c = 4 bytes
padding1 = 4 bytes 
inner structure = 16 bytes ( 4 bytes for ab, 4 bytes padding, 8 bytes for bc)
d = 4 bytes
padding2 = 4 bytes

sizeof(Test)返回40個字節。

我的問題:

  1. padding1 - >為什么這4個字節? 這是因為內部結構本身應該對齊嗎? (另外,它是與8字節(長)還是16字節(內部大小)邊界對齊。?)

  2. padding2 - >這是4字節填充,因為在結構內部完成了最大的對齊(這是8)??

謝謝,

  1. padding1 - >為什么這4個字節? 這是因為內部結構本身應該對齊嗎? (另外,它是與8字節(長)還是16字節(內部大小)邊界對齊。?)

這是因為內部struct應該是8字節對齊的,因此long可以可靠地進行8字節對齊。

  1. padding2 - >這是4字節填充,因為在結構內部完成了最大的對齊(這是8)??

它是這樣的,整個struct的大小是八個字節的倍數,因此內部struct可以在八字節邊界上適當地對齊。

在這種特殊情況下,如果匿名struct成員可以與獨立struct不同地處理,則只需要四個字節的填充就可以滿足對齊要求,但是6.7.2.1

14結構或聯合對象的每個非位字段成員都以適合其類型的實現定義方式對齊。

禁止那樣的。 因此,為了減小struct的大小,程序員需要重新排列它,將奇數個int成員移動到內部struct (或者生成int ab;以及long bc;直接成員的Test而不通過匿名struct )。

填充是非常依賴平台和編譯器的,即使您看到的行為非常常見。

通常(這不是C標准所說的),編譯器會對齊結構的成員,以減少內存訪問次數。 對於64位x86,內存訪問總是獲取8個字節,與64位邊界對齊。 換句話說,如果在地址0x1010AA45訪問1個字節,CPU將實際從地址0x01010AA40的 (高速緩存)內存中取出8個字節。

為了實現這樣的規則,如果成員是N字節長,則編譯器通常將N舍入到下一個2的冪,並將該成員與64位平台上的此類大小或8字節對齊,無論哪個更小。 大多數編譯器允許通過#pragma或配置調整此類規則。

我相信你的編譯器會添加Padding1,因為它有一個規則可以將所有結構與8字節邊界對齊,無論它們有多大。 或者,它也可以引入它,因為內部結構大於4個字節,因此需要對齊到8個字節。

Padding2可能是因為您可以創建一個struct Test數組。 為了保證所有結構都正確地對齊到8字節邊界 - 而不僅僅是數組中的第一項 - 最后定義了填充。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM