맞춤(C11)

C의 하위 수준 기능 중 하나는 하드웨어 아키텍처를 최대한 활용하기 위해 메모리 내 개체의 정확한 맞춤을 지정하는 기능입니다.

데이터 크기의 배수가 되는 주소에 데이터를 저장하면 CPU가 더 효율적으로 메모리를 읽고 쓸 수 있습니다. 예를 들어, 4바이트 정수는 4의 배수가 되는 주소에 저장된 경우 보다 효율적으로 액세스됩니다. 데이터가 맞춰져 있지 않으면 CPU가 더 많은 주소 계산 작업을 수행하여 데이터에 액세스합니다.

기본적으로 컴파일러는 데이터를 크기 기준으로 맞춥니다. 예를 들어, char는 1바이트 경계, short는 2바이트 경계, int, long 및 float는 4바이트 경계, double은 8바이트 경계 등입니다.

또한 자주 사용하는 데이터를 프로세서의 캐시 라인 크기에 맞추면 캐시 성능을 향상시킬 수 있습니다. 예를 들어, 크기가 32바이트보다 작은 구조체를 정의한다고 가정해 보겠습니다. 32바이트 맞춤을 사용하여 구조체의 모든 인스턴스가 효율적으로 캐시되도록 할 수 있습니다.

일반적으로는 맞춤에 대해 걱정할 필요가 없습니다. 컴파일러는 일반적으로 대상 프로세서 및 데이터 크기를 기반으로 한 자연 경계에 데이터를 맞춥니다. 32비트 프로세서에서는 최대 4바이트 경계에 데이터를 맞추고 64비트 프로세서에서는 8바이트 경계에 데이터를 맞춥니다. 그러나 데이터 구조에 대해 사용자 지정 맞춤을 지정하여 성능 향상이나 메모리 절약 효과를 얻을 수 있는 경우도 있습니다.

C11 키워드 _Alignof 를 사용하여 형식 또는 변수의 기본 맞춤을 가져오고, _Alignas 를 사용하여 변수 또는 사용자 정의 형식에 대한 사용자 지정 맞춤을 지정합니다.

에 정의된 편의 매크로 alignof 및 alignas<stdalign.h> 는 각각_Alignof 및_Alignas 에 직접 매핑됩니다. 이러한 매크로는 C++에서 사용되는 키워드와 일치됩니다. 따라서 C 키워드 대신 매크로를 사용하면 두 언어 간에 공유하는 코드가 있을 경우 코드 이식성에 도움이 될 수 있습니다.

alignas 및 _Alignas(C11)

alignas 또는 _Alignas 를 사용하여 변수 또는 사용자 정의 형식에 대한 사용자 지정 맞춤을 지정합니다. 구조체, 공용 구조체, 열거형 또는 변수에 적용할 수 있습니다.

alignas 구문

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

설명

_Alignas는 형식 정의, 비트 필드, 함수, 함수 매개 변수, 또는 register 지정자를 사용하여 선언된 개체의 선언에 사용할 수 없습니다.

1, 2, 4, 8, 16 등 2의 거듭제곱인 맞춤을 지정합니다. 형식의 크기보다 작은 값을 사용하지 마세요.

struct 및 union 형식에는 멤버 중 가장 큰 맞춤과 동일한 맞춤이 있습니다. 개별 멤버 맞춤 요구 사항이 충족되도록 패딩 바이트가 struct 내에 추가됩니다.

선언에 여러 개의 alignas 지정자가 있는 경우(예: struct에 alignas 지정자가 다른 여러 멤버가 포함됨) struct의 맞춤은 적어도 가장 큰 지정자의 값이 됩니다.

alignas 예제

이 예제에서는 C++로 이식할 수 있으므로 편의 매크로 alignof 를 사용합니다. _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 예제

이 예제에서는 C++로 이식할 수 있으므로 편의 매크로 alignof 를 사용합니다. _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) 이상. 최신 SDK를 다운로드하려면 Windows SDK를 참조하세요. C11 및 C17 개발을 위한 SDK를 설치하고 사용하기 위한 지침은 Visual Studio에 C11 및 C17 지원 설치를 참조하세요.

추가 정보

/std(언어 표준 버전 지정)
C++ alignof 및 alignas
데이터 맞춤의 컴파일러 처리