Share via


對齊 (C11)

C 的其中一個低階功能是能夠指定記憶體中物件的精確對齊方式,以充分利用硬體架構。

當 CPU 將資料儲存在多個資料大小的位址時,CPU 會更有效率地讀取和寫入記憶體。 例如,如果 4 位元組整數儲存在 4 倍數的位址上,則會更有效率地存取 4 位元組整數。 當資料未對齊時,CPU 會執行更多位址計算工作來存取資料。

根據預設,編譯器會根據其大小來對齊資料: char 在 1 位元組界限、 short 2 位元組界限、 intlongfloat 4 位元組界限上、 double 8 位元組界限等等。

此外,藉由將經常使用的資料與處理器的快取行大小對齊,您可以改善快取效能。 例如,假設您定義大小小於 32 個位元組的結構。 您可能想要使用 32 位元組對齊,以確保結構的所有實例有效率地快取。

通常,您不需要擔心對齊方式。 編譯器通常會根據目標處理器和資料大小,在自然界限上對齊資料。 資料會對齊 32 位處理器上最多 4 位元組的界限,以及 64 位處理器上的 8 位元組界限。 不過,在某些情況下,您可以為資料結構指定自訂對齊方式,以達到效能改善或省下記憶體。

使用 C11 關鍵字 _Alignof 取得類型或變數的慣用對齊方式,並 _Alignas 指定變數或使用者定義類型的自訂對齊方式。

在 中定義的便利宏 alignofalignas ,分別對應至 _Alignof_Alignas<stdalign.h> 這些宏符合 C++ 中使用的關鍵字。 因此,如果您在兩種語言之間共用任何程式碼,使用宏而非 C 關鍵字可能會對程式碼可攜性有所説明。

alignas_Alignas (C11)

使用 alignas_Alignas 指定變數或使用者定義類型的自訂對齊方式。 它們可以套用至結構、等位、列舉或變數。

alignas 語法

alignas(type)
alignas(constant-expression)
_Alignas(type)
_Alignas(constant-expression)

備註

_Alignas 無法在 typedef、bit-field、function、function 參數或以 register 規範宣告的物件中使用。

指定兩個乘冪的對齊方式,例如 1、2、4、8、16 等等。 請勿使用小於類型大小的值。

structunion 型別的對齊方式等於任何成員的最大對齊方式。 填補位元組會新增在 內 struct ,以確保符合個別成員對齊需求。

例如,如果宣告中有數 alignas 個規範 (, struct 具有數個具有不同 alignas 規範的成員) ,則 的 struct 對齊方式至少會是最大規範的值。

alignas 範例

此範例會使用便利宏 alignof ,因為它可移植到 C++。 如果您使用 _Alignof ,則行為會相同。

// Compile with /std:c11

#include <stdio.h>
#include <stdalign.h>

typedef struct 
{
    int value; // aligns on a 4-byte boundary. There will be 28 bytes of padding between value and alignas
    alignas(32) char alignedMemory[32]; // assuming a 32 byte friendly cache alignment
} cacheFriendly; // this struct will be 32-byte aligned because alignedMemory is 32-byte aligned and is the largest alignment specified in the struct

int main()
{
    printf("sizeof(cacheFriendly): %d\n", sizeof(cacheFriendly)); // 4 bytes for int value + 32 bytes for alignedMemory[] + padding to ensure  alignment
    printf("alignof(cacheFriendly): %d\n", alignof(cacheFriendly)); // 32 because alignedMemory[] is aligned on a 32-byte boundary

    /* output
        sizeof(cacheFriendly): 64
        alignof(cacheFriendly): 32
    */
}

alignof_Alignof (C11)

_Alignof 和其別名 alignof 會以指定類型的位元組傳回對齊方式。 它會傳回 類型的 size_t 值。

alignof 語法

alignof(type)
_Alignof(type)

alignof 範例

此範例會使用便利宏 alignof ,因為它可移植到 C++。 如果您使用 _Alignof ,則行為會相同。

// Compile with /std:c11

#include <stdalign.h>
#include <stdio.h>

int main()
{
    size_t alignment = alignof(short);
    printf("alignof(short) = %d\n", alignment); // 2
    printf("alignof(int) = %d\n", alignof(int)); // 4
    printf("alignof(long) = %d\n", alignof(long)); // 4
    printf("alignof(float) = %d\n", alignof(float)); // 4
    printf("alignof(double) = %d\n", alignof(double)); // 8

    typedef struct
    {
        int a;
        double b;
    } test;

    printf("alignof(test) = %d\n", alignof(test)); // 8 because that is the alignment of the largest element in the structure

    /* output
        
       alignof(short) = 2
       alignof(int) = 4
       alignof(long) = 4
       alignof(float) = 4
       alignof(double) = 8
       alignof(test) = 8
    */
}

規格需求

使用 /std:c11 編譯。

Windows SDK 10.0.20348.0 (2104 版) 或更新版本。 請參閱 Windows SDK 以下載最新的 SDK。 如需安裝和使用 SDK 以進行 C11 和 C17 開發的指示,請參閱 在 Visual Studio 中安裝 C11 和 C17 支援

另請參閱

/std (指定語言標準版本)
C++ alignofalignas
資料對齊的編譯器處理