user1205577
user1205577

Reputation: 2450

C++ pointer of specific bit size

My question is about pointing to chunks of memory of an odd size.

Let's say I have a struct declared like so:

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

Let's assume declaring specific bit fields in the struct is desireable (why we'd use the bit fields is not the question).

If I wanted to declare a pointer that points to one of those fields, I might try something like this:

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

Except that this produces the error "taking the address of a bit field is not allowed".

Assuming that we would want to, is there a way to point to those fields in this way? I know that C++ will probably pad the fields to the next byte (which in this case would be 32 bits).

Upvotes: 5

Views: 1094

Answers (3)

James Kanze
James Kanze

Reputation: 153909

There's no way to get a pointer to a bit field. If you're willing to implement an equivalent structure yourself, however, using shifts and masks, you should be able to define a smart pointer into it. Something like:

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

(This is just a rough idea. You'll probably want both a pointer and a pointer to const, and the lifetime of the proxy vs. that of its owner may be an issue.)

Upvotes: 0

dirkgently
dirkgently

Reputation: 111120

Except that this produces the error "taking the address of a bit field is not allowed".

This is explicitly disallowed by the standard. See [class.bit] 9.6/3:

The address-of operator & shall not be applied to a bit-field, so there are no pointers to bitfields.

A byte (which is CHAR_BIT bits wide, where CHAR_BIT is at least 8) is the minimum you can address.

Assuming that we would want to, is there a way to point to those fields in this way?

No. You can have a pointer to an object of the enclosing struct type though. This is a direct carry over from C; See C FAQ 2.26:

Bit-fields are inconvenient when you also want to be able to manipulate some collection of bits as a whole (perhaps to copy a set of flags).

You may want to look at other alternatives such std::bitset or boost::dynamic_bitset.

Upvotes: 6

Alok Save
Alok Save

Reputation: 206508

In C++, the smallest addressable value must have a size of at least 1 byte. So No you cannot take address of an bit field with pointers.

C++03 Standard 9.6 Bit-fields:
Para 3:

...The address-of operator& shall not be applied to a bit-field, so there are no pointers to bit-fields. ....

Upvotes: 12

Related Questions