문제

C ++ struct가있는 경우 64 비트 데이터 단어를 정의합니다.

struct SMyDataWord
{
    int Name : 40;
    int Colour : 24;
};

무엇을합니까 : 40 구문은 ... 처음 40 비트가 이름과 나머지 24 비트를 위해 예약되어 있음을 의미합니까?

이것이 사용되는 방식이지만 전에는 접근하지 못했습니다.

도움이 되었습니까?

해결책

C에서 이월 된 비트 필드 Name 너비는 40 비트이며 Colour 폭 24 비트입니다. 따라서 구조물에는 64 비트 이상이 있습니다. 내 시스템에서 64 비트는 8 바이트입니다.

다른 팁

예, 그것은 구문입니다 비트 필드. 그들은 일반적으로 하드웨어 레지스터에 매핑되는 스트러크를 정의하는 데 사용됩니다. 사용하기로 결정한 경우 명심해야 할 사항이 있습니다. 하나는 필드를 구성하는 실제 바이트에서 컴파일러가 어떻게 레이아웃, 주문 및 패딩을 수행하는지 알 수 없다는 것입니다. 동일한 컴파일러이지만 최적화 설정이 다릅니다).

그것은 비트 필드 정의입니다.

이름은 정확히 40 비트의 정보를 저장할 수있는 정수입니다. 색상은 24 비트를 저장할 수 있습니다.

이것은 종종 필요한 구조물로 일부 공간을 절약하거나 CPU에 대해 쉽게 처리 할 수있는 크기로 코드를 압축하기 위해 수행됩니다 (귀하의 경우 64 비트. 64 비트 기계의 CPU 레지스터에 정확히 맞습니다).

비트 필드에 액세스하는 코드는 약간 느리게 실행됩니다.

신중하게 사용하십시오:

비트 필드에 관한 거의 모든 것이 구현에 따라 다릅니다. 예를 들어, 비트가 왼쪽에서 오른쪽으로 저장되는지 또는 오른쪽에서 왼쪽에서 오른쪽으로 저장되는지 여부는 실제 하드웨어 아키텍처에 따라 다릅니다. 또한 각 컴파일러는 다른 멤버 정렬 모델을 사용하므로 최적화 된 BillingRec의 크기는 9가 아닌 12 바이트입니다. 비트 필드의 주소를 가져갈 수 없거나 비트 배열을 만들 수 없습니다. 마지막으로, 대부분의 구현에서 비트 필드의 사용은 속도 오버 헤드가 발생합니다. 따라서 코드를 최적화 할 때 코드를 사용하기 전에 특정 최적화와 그 트레이드 오프의 효과를 측정하십시오.

여기 sizeof 후드 아래에서 무슨 일이 일어나고 있는지 잘 보여줍니다.

#include <iostream>
#include <climits>

struct bc_1 {
   int a : 1;
   int b : 1;
};

struct bc_2 {
   int a : 31;
   int b : 1;
};

struct bc_3 {
   int a : 32;
   int b : 1;
};

struct bc_4 {
   int a : 31;
   int b : 2;
};

struct bc_5 {
   int a : 32;
   int b : 32;
};

struct bc_6 {
   int a : 40;
   int b : 32;
};

struct bc_7 {
   int a : 63;
   int b : 1;
};

int main(int argc, char * argv[]) {
    std::cout << "CHAR_BIT = " << CHAR_BIT;
    std::cout << " => sizeof(int) = " << sizeof(int) << std::endl;

    std::cout << "1,  1:  " << sizeof(struct bc_1) << std::endl;
    std::cout << "31, 1:  " << sizeof(struct bc_2) << std::endl;
    std::cout << "32, 1:  " << sizeof(struct bc_3) << std::endl;
    std::cout << "31, 2:  " << sizeof(struct bc_4) << std::endl;
    std::cout << "32, 32: " << sizeof(struct bc_5) << std::endl;
    std::cout << "40, 32: " << sizeof(struct bc_6) << std::endl;
    std::cout << "63, 1:  " << sizeof(struct bc_7) << std::endl;
}

다음은 컴파일러 및 OS 및 하드웨어에 따라 다릅니다. GCC-7이있는 MACOS에서 (a CHAR_BIT = 8, 32 비트 int (즉, 64 비트의 절반 long) 가지다 sizeof(int) = 4) 이것은 내가 본 출력입니다.

CHAR_BIT = 8 => sizeof(int) = 4
1,  1:  4
31, 1:  4
32, 1:  8
31, 2:  8
32, 32: 8
40, 32: 12
63, 1:  8

이것은 우리에게 몇 가지를 알려줍니다. int 유형은 단일에 맞습니다 int (위의 예에서 32 비트), 컴파일러는 단일 만 할당됩니다. int기억의 가치 (bc_1 그리고 bc_2). 한 번, 싱글 int 더 이상 비트 필드를 붙잡을 수없고 두 번째를 추가합니다 (bc_3 그리고 bc_4). 주목하십시오 bc_5 용량이 있습니다.

흥미롭게도, 우리는 허용보다 더 많은 비트를 "선택"할 수 있습니다. 보다 bc_6. 여기서 G ++ -7은 경고를합니다.

bitfields.cpp::30:13: warning: width of 'bc_6::a' exceeds its type
     int a : 40;
             ^~

참고 : Clang ++는 이것을 더 자세히 설명합니다.

bitfields.cpp:30:9: warning: width of bit-field 'a' (40 bits) exceeds the width of its type; value will be truncated to 32 bits [-Wbitfield-width]
    int a : 40;
    ^

그러나 후드 아래에서 컴파일러가 다른 사람을 할당하는 것 같습니다. int기억의 가치. 또는 최소한 올바른 크기를 결정합니다. 컴파일러 가이 메모리에 액세스하지 말라고 경고하는 것 같습니다. int a = bc_6::a (나는 그것을 베팅 할 것이다 int a 그런 다음 처음 32 비트의 필드 만 있으면됩니다. bc_6::a...). 이것은 확인됩니다 bc_7 총 크기는 두 가지입니다 intS, 그러나 첫 번째 필드는 대부분을 다룹니다.

마지막으로 교체 int ~와 함께 long 위의 예에서 예상대로 작동합니다.

CHAR_BIT = 8 => sizeof(long) = 8
1,  1:  8
31, 1:  8
32, 1:  8
31, 2:  8
32, 32: 8
40, 32: 16
63, 1:  8
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top