2012-06-19 38 views
5

Câu hỏi của tôi là trỏ đến các khối bộ nhớ có kích thước lẻ.Con trỏ C++ có kích thước bit cụ thể

Hãy nói rằng tôi có một struct tuyên bố như vậy:

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

Giả tuyên bố các lĩnh vực bit cụ thể trong struct là tuyệt (lý do tại sao chúng tôi muốn sử dụng các lĩnh vực chút không phải là câu hỏi).

Nếu tôi muốn khai báo một con trỏ trỏ đến một trong những lĩnh vực, tôi có thể thử một cái gì đó như thế này:

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

Ngoại trừ việc này tạo ra lỗi "lấy địa chỉ của một trường bit không phải là được phép ".

Giả sử rằng chúng tôi muốn, có cách nào chỉ ra các trường đó theo cách này không? Tôi biết rằng C + + có lẽ sẽ pad các lĩnh vực để byte tiếp theo (trong trường hợp này sẽ là 32 bit).

+3

Vì con trỏ "điểm" thành byte, tôi cho rằng hành vi này là bình thường, vì không có cách nào để lưu trữ địa chỉ của một thứ có thể không phải là một byte "hoàn chỉnh". – ereOn

+1

Tôi không tin rằng bạn sẽ thấy bất kỳ phần đệm nào cho các thành viên bitfield có kích thước bit được chỉ định (hoặc ít nhất, bạn không thể chắc chắn về việc nhận được bất kỳ phần nào - nó được triển khai thực hiện). – RichieHindle

+0

@RichieHindle: thực sự, và đối với hầu hết các giá trị nhỏ, sẽ không có đệm, vì đây chính là lý do bitfields được phát minh. – PlasmaHH

Trả lời

11

Trong C++, giá trị địa chỉ nhỏ nhất phải có kích thước tối thiểu là 1 byte. Vì vậy, Không, bạn không thể lấy địa chỉ của một trường bit với con trỏ.

C++ 03 Tiêu chuẩn 9.6 Bit-lĩnh vực:
Para 3:

... Địa chỉ-của nhà điều hành & sẽ không được áp dụng cho một trường bit, do đó không có con trỏ tới các trường bit. ....

6

Ngoại trừ việc này tạo ra lỗi "lấy địa chỉ của một trường bit không được phép".

Điều này rõ ràng không được phép theo tiêu chuẩn. Xem [class.bit] 9.6/3:

Địa chỉ-của nhà điều hành & sẽ không được áp dụng cho một trường bit, vì vậy không có con trỏ để bitfields.

Một byte (là CHAR_BIT bit rộng, trong đó CHAR_BIT ít nhất là 8) là mức tối thiểu bạn có thể giải quyết.

Giả sử rằng chúng tôi muốn, có cách nào chỉ ra các trường đó theo cách này không?

Không. Bạn có thể có con trỏ đến đối tượng thuộc loại struct kèm theo. Đây là một chuyển tiếp trực tiếp từ C; Xem C FAQ 2.26:

Trường bit là bất tiện khi bạn cũng muốn có thể thao tác một số tập hợp toàn bộ bit (có thể sao chép một bộ cờ).

Bạn có thể muốn xem các lựa chọn thay thế khác như std::bitset hoặc boost::dynamic_bitset.

0

Không có cách nào để đưa con trỏ đến trường bit. Tuy nhiên, nếu bạn sẵn sàng tự mình thực hiện một cấu trúc tương đương, hãy sử dụng các thay đổi và mặt nạ, bạn sẽ có thể xác định con trỏ thông minh vào đó. Một cái gì đó như:

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); 
    } 
}; 

(Đây chỉ là một ý tưởng thô Có thể bạn sẽ muốn cả một con trỏ và một con trỏ để const, và tuổi thọ của proxy vs rằng các chủ nhân của nó có thể là một . Vấn đề.)

Các vấn đề liên quan