2017-01-05 3 views
0

에서 비트 필드의 정렬, 내가 편리하게 2 바이트 값에 액세스 할 수있는 노동 조합 만들려고 해요 : 나는 pixel.r = 5를 볼 것으로 예상하고 있습니다VStudio C++ VStudio 2010 년 노동 조합

#pragma pack(push,1) // disable padding 
typedef struct { 
    uint8_t r:3; 
    uint8_t g:3; 
    uint8_t b:3; 
}tsRgb; 

typedef union { 
    uint16_t raw; 
    tsRgb rgb; 
}tPixelData; 
#pragma pack(pop) 

int main(){ 
    tPixelData pixel; 
    pixel.raw = 0xABE5; 
    return 0; 
} 

을, pixel.g = 4, pixel.b = 7 r과 g는 괜찮지 만 b는 3입니다.

무엇이 잘못 되었나요? 나는 비트를 올바르게 정렬하지 않는다고 가정한다.

+0

참조 : http://stackoverflow.com/questions/6043483/whybit-endianness-is-an-issue-in-bitfields/6044223#6044223 – Lundin

+0

표준은 비트 필드에 대해 거의 보장하지 않습니다. '((un) signed) int'와'_Bool' 타입 만이 보증됩니다. – Olaf

+0

downvoter 설명 해주십시오. 고맙습니다. –

답변

4

세 번째 필드는 별도의 바이트입니다.

VC++에서 비트 필드는 기본 유형의 경계를 넘지 않습니다. 3 + 3 비트를 사용하면 2 비트 만 남아 있으므로 다음 필드는 새로운 바이트에서 3 비트를 사용합니다.

uint8_t 대신 uint16_t을 사용하면 더 효과적 일 수 있습니다.

"패딩 사용 안 함"은 비트 수준이 아니라 바이트 수준에서 작동합니다.

+0

우수! 이제 작동합니다. 고마워요! –

+0

* 비트 필드는 기본 유형의 경계를 넘지 않습니다. * 구현 정의입니다. OP가 사용하는 VStudio 구현에서 경계를 넘지는 못하지만 비트 필드는 기본 저장 단위의 경계를 매우 잘 넘을 수 있습니다. 비트 필드는 * 극히 * 구현에 따라 다르며 극히 * 휴대용이 아닙니다. –

+1

@Andrew - Ok, OP가 사용하고있는 시스템에 대한 대답이 명확하다는 설명을 추가했습니다. –

3

비트 필드를 사용하는 것은 근본적으로 문제가 있습니다. the C Standard 당, 6.7.2.1 구조 및 노동 조합 지정자 (질문도 C 태그 때문에) 문단 11 :

구현은 비트 - 필드를 보유 할 충분한 어떤 주소 저장 장치를 할당 할 수 있습니다. 충분한 공간이 남아있는 경우, 구조의 다른 비트 필드 바로 뒤에 오는 비트 필드 은 이 같은 단위의 인접 비트로 패킹되어야합니다. 불충분 한 공간 인 이 남아 있으면 적합하지 않은 비트 필드가 에 삽입되는지 또는 인접한 유닛과 중복되는지 여부는 구현 정의 된 입니다. 단위 (고위 순서에서 하위 순서 또는 하위 순서에서 상위 순서로) 내의 비트 필드 할당 순서는 구현 정의입니다. 주소 지정 가능한 스토리지 유닛의 정렬이 지정되지 않았습니다.

비트 필드의 비트 레이아웃 및 정렬은 모두 구현에 따라 정의됩니다. 필드는 저장 단위 경계를 넘을 수도 있고 그렇지 않을 수도 있습니다. 저장 순서는 임의의 순서로 저장할 수 있습니다.

휴대형이 아닙니다.

+0

그들은 on-the-wire 비트 형식과 일치하는 이식 가능한 방법이 아닙니다. 그것들은 구조체의 메모리 소비를 줄이기위한 이식성있는 방법이다 (그리고 그것들은 모두 사용해야한다.) –