인프런 커뮤니티 질문&답변

몽글구름님의 프로필 이미지

작성한 질문수

홍정모의 따라하며 배우는 C언어

15.11 비트필드의 패딩

15.11 비트 필드 질문입니다.

해결된 질문

23.07.24 12:45 작성

·

414

·

수정됨

1

안녕하세요.

일단 저는 MacOS 환경에서 Visual Studio Code에 extention을 설치해서 듣고 있습니다.

int main()
{
    struct
    {
        bool option1 : 7;
        // bool      : 0;  // 자료형만큼의 크기가 더 할당됨. 패딩이 많이 들어가도 상관없으니 강제로 메모리를 더 달라.
        bool option2 : 1;
        // unsigned long long option3 : 16;
    } bbf;

    printf("%zu bytes\n", sizeof(bbf));

    struct
    {
        unsigned int option1 : 32;
        // unsigned int : 0;
        unsigned int option2 : 1;
        // bool option3 : 1;
    } uibf;

    printf("%zu bytes\n", sizeof(uibf));

    return 0;
}

근데 예제를 따라하다가 bool option1 : 7;을 하니까 교수님과는 달리 제 환경에선 에러가 나더라고요...

에러 메시지는 " error: width of bit-field 'option1' (7 bits) exceeds the width of its type (1 bit) " 였습니다.

그래서 나름 찾아봤는데

"In the C programming language, the width of a bit-field cannot exceed the width of the underlying type, and whether int bit-fields that are not explicitly signed or unsigned are signed or unsigned is implementation-defined. For example, int b:3; may have the range of values 0..7 or -4..3 in C, but only the latter choice is allowed in C++." (출처 : https://en.cppreference.com/w/cpp/language/bit_field )

구글 번역을 참고해서 보니까 (영어를 잘하지 않아서 혹시 제가 잘못 이해한 부분이 있다면 알려주시면 감사하겠습니다.) 대충 비트필드의 넓이를 기본형식의 넓이가 초과할 수 없다는 것 같은데...

unsigned int option1 : 32;는 되는데 unsigned int option1 : 33;하니까 비슷한 에러 " width of bit-field 'option1' (33 bits) exceeds the width of its type (32 bits) " 가 나오네요.

int는 그렇다쳐도 bool의 크기는 1바이트니까 비트필드 안에서 7비트 선언하는게 왜 에러가 나오는지 혹시 알 수 있을까요? (구조체 안에 bool option1 : 1;로만 정의하면 또 괜찮아요..)

 

답변 1

2

Soobak님의 프로필 이미지

2023. 07. 24. 14:12

안녕하세요, 답변 도우미 Soobak 입니다.

질문해주신 내용에 대하여 저도 궁금하여 이것 저것 자료들을 찾아보았는데요.
출처로 첨부해주신 링크에서 발췌해주신 문장은 옳게 이해하신 것 같습니다.

우선, 메모리를 배정받을 수 있는 최소 단위가 1byte 이기 때문에, bool 자료형 역시 1byte 의 크기를 가지고 있지만, 실제 사용하는 데이터는 1 혹은 01bit 입니다.

이 때, 남는 나머지 7bits 의 처리에 대한 표준 정의가 명확하지 않으며,
비트필드 동작에 대한 구현 방식이 컴파일러와 플랫폼마다 다를 수 있다고 합니다.

또한, C 언어에서 <stdbool.h> 헤더의 bool 자료형, 또는 _Bool 자료형은 C99 부터 등장하였으며, 마찬가지로 구현 방식이 컴파일러와 플랫폼마다 다를 수 있다고 합니다.

따라서, 컴파일러와 플랫폼 마다 bool 자료형의 비트 필드 너비를 1 비트 이상으로 설정하는 것을 허용할 수도, 그렇지 않을 수도 있다고 합니다.

즉, 표준 정의가 명확하지 않아 생긴 컴파일러와 환경에 따른 문제로 이해하시는 것이 적절할 것 같습니다.

참고로, 제가 Windows 환경에서 Visual Studio 2022 로 동일한 코드를 컴파일을 진행했을 때는 정상적으로 완료가 됩니다. Linux 가상머신 환경에서, gcc 컴파일러로 컴파일을 했을 때에도 정상적으로 완료가 되네요.
Visual studio code 는 컴파일러가 아닌 편집기이므로, 사용하시는 컴파일러를 확인해보시는 것이 좋을 것 같습니다.

참고 문서 링크를 첨부드립니다. (영어가 아닌 한글로된 문서를 첨부드리고 싶었으나, 찾기가 쉽지 않네요...🥲)
C++bitfield packing with bools - Stack overflow(링크)

몽글구름님의 프로필 이미지
몽글구름
질문자

2023. 07. 24. 15:17

감사합니다. 다음 강의에서 교수님이 알려주신 방법으로 컴파일러를 확인해보니 'clang detected version 14.0', 'gcc detected version 4.2' 이렇게 두 개 다 나오네요. ㅎㅎ