簡體   English   中英

C-alignas沒有給出預期的結果

[英]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 Astruct 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。

您已指定Bb元素在4字節邊界上對齊。 由於a只需要2個字節,這導致2個字節的填充之間ab ,和另一2個字節后b使結構作為一個整體的4個字節的倍數。

對於A ,只有a具有4個字節的對齊方式(通過在結構的開頭進行對齊)。 b沒有額外的對齊要求,因此緊接也沒有填充,並且最后也不需要填充。

它們不同的原因是

sizeof給出存儲其類型或實例所需的實際大小(以字節為單位)。

alignof為您提供最大元素所需的字節對齊方式。

暫無
暫無

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

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