수색…


소개

비트 필드는 C 및 C ++ 구조를 단단히 묶어 크기를 줄입니다. 이것은 어려움없이 나타납니다. 멤버의 비트 수를 지정하면 컴파일러가 비트를 공동으로 작업합니다. 이 제한은 비트 필드 멤버가 공동으로 저장되기 때문에 비트 필드 멤버의 주소를 가져올 수 없다는 것입니다. sizeof() 도 허용되지 않습니다.

비트 필드의 비용은 액세스가 느려지므로 메모리를 검색하고 멤버 값을 추출하거나 수정하기 위해 비트 연산을 적용해야합니다. 이러한 작업은 실행 가능 크기에 추가됩니다.

비고

비트 연산은 얼마나 비쌉니까? 간단한 비 비트 필드 구조를 가정 해보십시오.

struct foo {
    unsigned x;
    unsigned y;
}
static struct foo my_var;

나중에 코드에서 :

my_var.y = 5;

sizeof (unsigned) == 4 이면 구조체의 시작 부분에 x가 저장되고 y는 4 바이트로 저장됩니다. 생성 된 어셈블리 코드는 다음과 유사 할 수 있습니다.

loada register1,#myvar     ; get the address of the structure
storei register1[4],#0x05  ; put the value '5' at offset 4, e.g., set y=5

이것은 x가 y와 공존하지 않기 때문에 간단합니다. 그러나 비트 필드를 사용하여 구조를 재정의한다고 상상해보십시오.

struct foo {
    unsigned x : 4; /* Range 0-0x0f, or 0 through 15 */
    unsigned y : 4;
}

xy 는 모두 4 비트로 할당되어 단일 바이트를 공유합니다. 따라서 구조체는 8 대신에 1 바이트를 차지합니다. 어셈블리가 y 를 설정하도록 고려합니다. 상위 nibble에서 끝나는 것으로 가정합니다.

loada  register1,#myvar        ; get the address of the structure
loadb  register2,register1[0]  ; get the byte from memory
andb   register2,#0x0f         ; zero out y in the byte, leaving x alone
orb    register2,#0x50         ; put the 5 into the 'y' portion of the byte
stb    register1[0],register2  ; put the modified byte back into memory

이러한 구조가 수천 또는 수백만 개에 이르면 좋은 트레이드 오프가 될 수 있으며, 캐시에 메모리를 유지하거나 스왑 핑을 방지하는 데 도움이되거나 이러한 문제를 악화시키고 처리 속도를 저하시킬 수있는 실행 파일을 부 풀릴 수 있습니다. 모든 것과 마찬가지로 좋은 판단을 사용하십시오.

장치 드라이버 사용 : 비트 필드를 장치 드라이버에 대한 영리한 구현 전략으로 사용 하지 마십시오. 비트 필드 저장 레이아웃은 컴파일러간에 반드시 일관성이 없으므로 이러한 구현을 이식 할 수 없게 만듭니다. 설정 값에 대한 읽기 - 수정 - 기록은 예상치 못한 동작을 야기하는 장치가 기대하는 것을 수행하지 않을 수 있습니다.

선언 및 사용

struct FileAttributes
{
    unsigned int ReadOnly: 1;    
    unsigned int Hidden: 1;
};

이 두 필드는 각각 메모리에서 1 비트를 차지합니다. 다음에 의해 지정됩니다 : 1 변수 이름 뒤에 : 1 표현식. 비트 필드의 기본 유형은 모든 정수 유형 (8 비트 int에서 64 비트 int)이 될 수 있습니다. unsigned 유형을 사용하는 것이 좋습니다. 그렇지 않으면 놀라움이 올 수 있습니다.

더 많은 비트가 필요한 경우 "1"을 필요한 비트 수로 대체하십시오. 예 :

struct Date
{
    unsigned int Year : 13; // 2^13 = 8192, enough for "year" representation for long time
    unsigned int Month: 4;  // 2^4 = 16, enough to represent 1-12 month values.
    unsigned int Day:   5;  // 32
};

전체 구조는 22 비트를 이용하고, 정상 컴파일러 설정 상태 sizeof 이 구성 4 바이트 일 것이다.

사용법은 매우 간단합니다. 그냥 변수를 선언하고 일반 구조처럼 사용하십시오.

Date d;

d.Year = 2016;
d.Month = 7;
d.Day =  22;

std::cout << "Year:" << d.Year << std::endl <<
        "Month:" << d.Month << std::endl <<
        "Day:" << d.Day << std::endl;


Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow