2012-06-19 2 views
5

제 질문은 이상한 크기의 메모리 덩어리를 가리키는 것입니다.특정 비트 크기의 C++ 포인터

의 난과 같이 선언 struct 있다고 가정 해 봅시다 :

typedef struct{ 
    int32 val1 : 29; 
    int32 val2 : 26; 
    char val3; 
}MyStruct; 

이 구조체으로 바람직하다에서의 특정 비트 필드를 선언 가정하자 (우리는 비트 필드를 사용하십시오 왜 질문하지 않습니다). 이 아닌 비트 필드의 주소를 복용 오류 "을 생산하는 것을 제외하고

MyStruct test; 
int32 *myPtr = &(test.val1); 

: 그 필드 중 하나를 가리키는 포인터를 선언하고 싶었다면

, 나는 이런 식으로 뭔가를 시도 할 수 있습니다 허용 ".

우리가 원한다고 가정 할 때,이 방법으로 필드를 가리키는 방법이 있습니까? 나는 C++이 필드를 다음 바이트 (이 경우에는 32 비트)에 채울 것임을 알고있다.

+3

포인터는 "포인트"를 바이트로 사용하기 때문에 "정상"바이트가 아닐 수도있는 주소를 저장할 방법이 없으므로이 동작이 정상적인 것으로 예상됩니다. – ereOn

+1

비트 크기가 지정된 비트 필드 멤버에 대해 패딩이 표시되지 않는다고 생각합니다 (또는 적어도 구현을 정의하지는 않습니다). – RichieHindle

+0

@RichieHindle : 사실, 대부분의 작은 값에 대해서는, 비트 필드가 발명 된 이유이기 때문에 패딩이 없습니다. – PlasmaHH

답변

11

C++에서 주소 지정 가능한 최소값은 최소 1 바이트 크기 여야합니다. 그래서 아니오, 포인터로 비트 필드의 주소를 가져올 수 없습니다.

C++ 03 9.6 표준 비트 필드 :
파라 3

... 운영자 & 어드레스의 지금이, 비트 필드에 적용 할 수 없다 비트 필드에 대한 포인터가 아닙니다. ....

6

이 오류가 발생한다는 점을 제외하고 "비트 필드의 주소를 복용은 허용되지 않습니다."

이것은 표준에 의해 명시 적으로 허용되지 않습니다.

오퍼레이터 & 어드레스의 비트 필드에 적용되므로 비트 필드에는 포인터가 없을되지 아니한다 [class.bit] 9.6/3 참조. (CHAR_BIT 적어도 CHAR_BIT 8 비트 폭)

바이트는 해결할 수있는 최소이다.

우리가 원한다고 가정 할 때, 이러한 방식으로 필드를 가리키는 방법이 있습니까?

아니요. struct 유형의 객체를 가리키는 포인터를 사용할 수 있습니다. 이것은 C에서 직접 가져온 것입니다. C FAQ 2.26을 참조하십시오 :

일부 비트 집합을 조작하려는 경우 (플래그 집합을 복사하는 등) 비트 필드는 불편합니다.

std::bitset 또는 boost::dynamic_bitset과 같은 다른 대안을 볼 수도 있습니다.

0

비트 필드에 대한 포인터를 가져올 방법이 없습니다. 만약 이 쉬프트와 마스크를 사용하여 동일한 구조를 직접 구현한다면, 스마트 포인터를 정의 할 수 있어야합니다. 같은 뭔가 :

class BitFieldPointer 
{ 
    unsigned* myData; 
    unsigned myMask; 
    unsigned myShift; 

    class DereferenceProxy 
    { 
     BitFieldPointer const* myOwner; 
    public: 
     DereferenceProxy(BitFieldPointer const* owner) : myOwner(owner) {} operator unsigned() const 
     { 
      return (*myOwner->myData && myOwner->myMask) >> myOwner->myShift; 
     } 

     void operator=(unsigned new_value) const 
     { 
      *myData = (*myOwner->myData && ~myOwner->myMask) | 
        ((new_value << myOwner->myShift) && myOwner->myMask); 
     } 
    }; 
public: 
    // ... 
    DereferenceProxy operator*() const 
    { 
     return DereferenceProxy(this); 
    } 
}; 

(이건 그냥 거친 생각입니다 당신은 아마이 될 수있는 포인터와 const를에 포인터, 그 소유자 의 대 프록시의 수명을 모두 할 것입니다. 문제가됩니다.)