Namespaces
Variants

Bit-fields

From cppreference.net

명시적인 너비(비트 단위)를 가진 멤버를 선언합니다. 인접한 비트 필드 멤버들은 개별 바이트를 공유하고 걸쳐서 패킹될 수 있습니다.

비트 필드 선언은 다음과 같은 struct 또는 union 멤버 선언으로, 선언자 를 사용합니다:

identifier  (선택 사항) : width
identifier - 선언되는 비트 필드의 이름. 이름은 선택사항: 이름 없는 비트 필드는 지정된 수의 비트 패딩을 도입함
width - 기본 타입의 비트 수보다 크거나 같고 0보다 크거나 같은 정수 상수 표현식 . 0보다 클 경우, 이 비트 필드가 차지할 비트 수입니다. 값 0은 이름 없는 비트 필드에서만 허용되며 특별한 의미를 가짐: 클래스 정의에서 다음 비트 필드가 할당 단위 경계에서 시작하도록 지정합니다.

목차

설명

비트 필드는 다음 (아마도 const 또는 volatile 한정된) 타입 중 하나만 가질 수 있습니다:

  • unsigned int , 부호 없는 비트 필드용 (예: unsigned int b : 3 ; 의 범위는 [ 0 , 7 ] )
  • signed int , 부호 있는 비트 필드용 ( signed int b : 3 ; 의 범위는 [ - 4 , 3 ] )
  • int , 구현에 따라 부호가 결정되는 비트 필드용 (이 키워드의 의미는 다른 모든 곳에서 "signed int"를 의미하는 것과 다름에 유의). 예를 들어, int b : 3 ; 의 값 범위는 [ 0 , 7 ] 또는 [ - 4 , 3 ] 일 수 있습니다.
  • _Bool , 1비트 비트 필드(예: bool x : 1 ; )의 범위는 [ 0 , 1 ] 이며, 여기로/에서의 암시적 변환 은 불리언 변환 규칙을 따릅니다.
(C99부터)
  • 비트 정밀 정수 타입(예: _BitInt ( 5 ) : 4 ; 의 범위는 [ - 8 , 7 ] 이고, unsigned _BitInt ( 5 ) : 4 ; 의 범위는 [ 0 , 15 ] 입니다.
(C23부터)

추가적인 구현 정의 타입들이 허용될 수 있습니다. 비트 필드가 atomic 타입을 가질 수 있는지 여부도 구현 정의입니다. (since C11) 비트 필드의 비트 수( width )는 그것이 보유할 수 있는 값의 범위에 제한을 설정합니다:

#include <stdio.h>
struct S
{
    // 3비트 부호 없는 필드,
    // 허용 값은 0...7
    unsigned int b : 3;
};
int main(void)
{
    struct S s = {7};
    ++s.b; // 부호 없는 오버플로
    printf("%d\n", s.b); // 출력: 0
}

여러 개의 인접한 비트 필드는 함께 패킹되는 것이 허용되며(일반적으로 그렇게 됩니다):

#include <stdio.h>
struct S
{
    // 일반적으로 4바이트를 차지함:
    // 5 bits: b1의 값
    // 11 bits: 사용되지 않음
    // 6 bits: b2의 값
    // 2 bits: b3의 값
    // 8 bits: 사용되지 않음
    unsigned b1 : 5, : 11, b2 : 6, b3 : 2;
};
int main(void)
{
    printf("%zu\n", sizeof(struct S)); // 일반적으로 4를 출력
}

특별한 이름 없는 비트 필드 width 가 0인 경우 패딩을 분리합니다: 이것은 다음 비트 필드가 다음 할당 단위의 시작 부분에서 시작하도록 지정합니다:

#include <stdio.h>
struct S
{
    // 일반적으로 8바이트를 차지함:
    // 5 bits: b1의 값
    // 27 bits: 사용되지 않음
    // 6 bits: b2의 값
    // 15 bits: b3의 값
    // 11 bits: 사용되지 않음
    unsigned b1 : 5;
    unsigned    : 0; // 새로운 unsigned int 시작
    unsigned b2 : 6;
    unsigned b3 : 15;
};
int main(void)
{
    printf("%zu\n", sizeof(struct S)); // 일반적으로 8을 출력
}

비트 필드는 바이트의 시작 부분에서 시작하지 않을 수 있으므로, 비트 필드의 주소를 취할 수 없습니다. 비트 필드에 대한 포인터는 불가능합니다. 비트 필드는 sizeof _Alignas (C11부터) (C23까지) alignas (C23부터) (C11부터) 와 함께 사용할 수 없습니다.

참고 사항

다음 비트 필드 사용법은 정의되지 않은 동작 을 유발합니다:

비트 필드의 다음 속성들은 명시되지 않음 :

  • 비트 필드를 보유하는 할당 단위의 정렬.

비트 필드의 다음 속성들은 구현 시 정의됨 입니다:

  • int 타입의 비트 필드가 부호 있는 정수로 처리되는지 아니면 부호 없는 정수로 처리되는지 여부.
  • int , signed int , unsigned int , _Bool (C99부터) , 그리고 (가능하다면 unsigned ) _BitInt ( N ) (C23부터) 이외의 타입들이 허용되는지 여부.
  • atomic 타입 허용 여부.
(since C11)
  • 비트 필드가 할당 단위 경계를 넘을 수 있는지 여부.
  • 할당 단위 내에서 비트 필드의 순서 (일부 플랫폼에서는 비트 필드가 왼쪽에서 오른쪽으로 패킹되고, 다른 플랫폼에서는 오른쪽에서 왼쪽으로 패킹됨).

_Bool 객체 표현의 비트 수가 최소 CHAR_BIT 임에도 불구하고, _Bool 타입의 비트 필드 너비 1 보다 클 수 없습니다.

(C99부터)

C++ 프로그래밍 언어에서, 비트 필드의 너비는 기본 타입의 너비를 초과할 수 있습니다 (그러나 추가 비트들은 패딩 비트입니다). 또한 int 타입의 비트 필드는 항상 부호 있는(signed) 타입입니다.

참고문헌

  • C23 표준 (ISO/IEC 9899:2024):
  • 6.7.2.1 구조체 및 공용체 지정자
  • C17 표준 (ISO/IEC 9899:2018):
  • 6.7.2.1 구조체 및 공용체 지정자
  • C11 표준 (ISO/IEC 9899:2011):
  • 6.7.2.1 구조체 및 공용체 지정자
  • C99 표준 (ISO/IEC 9899:1999):
  • 6.7.2.1 구조체 및 공용체 지정자
  • C89/C90 표준 (ISO/IEC 9899:1990):
  • 3.5.2.1 구조체 및 공용체 지정자

참고 항목

C++ 문서 for Bit-field