Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c - cannot take address of bit-field

Why cannot take address of bit-field?

How do I make a pointer to bit-field?

Here is the code...

struct bitfield {
    unsigned int a: 1;
    unsigned int b: 1;
    unsigned int c: 1;
    unsigned int d: 1;
};

int main(void)
{
    struct bitfield pipe = {
        .a = 1, .b = 0,
        .c = 0, .d = 0
    };
    printf("%d %d %d %d\n", pipe.a,
            pipe.b, pipe.c, pipe.d);
    printf("%p\n", &pipe.a); /* OPPS HERE */
    // error: cannot take address of bit-field ...
    return 0;
}
like image 688
sleepy_dog Avatar asked Nov 25 '12 01:11

sleepy_dog


3 Answers

Bitfields members are (typically) smaller than the granularity allowed by pointers, which is the granularity of chars (by definition of char, which by the way is mandated to be 8 bit long at least). So, a regular pointer doesn't cut it.

Also, it wouldn't be clear what would be the type of a pointer to a bitfield member, since to store/retrieve such a member the compiler must know exactly where it is located in the bitfield (and no "regular" pointer type can carry such information).

Finally, it's hardly a requested feature (bitfields aren't seen often in first place); bitfields are used to store information compactly or to build a packed representation of flags (e.g. to write to hardware ports), it's rare that you need a pointer to a single field of them - and if it's needed, you can always resort to a regular struct and convert to bitfield at the last moment.

For all these reasons, the standard says that bitfields members aren't addressable, period. It could be possible to overcome these obstacles (e.g. by defining special pointer types that store all the information needed to access a bitfield member), but it would be yet another overcomplicated dark corner of the language that nobody uses.

like image 108
Matteo Italia Avatar answered Oct 12 '22 19:10

Matteo Italia


You cannot have the address of a bit field, because the smallest addressable unit is a byte (remembering that bytes in C may not necessarily be 8 bits wide).

The best you could hope for is the address of the containing structure.

The relevant part of the (C11) standard is section 6.5.3.2 Address and indirection operators (my italics):

The operand of the unary & operator shall be either a function designator, the result of a [] or unary * operator, or an lvalue that designates an object that is not a bit-field and is not declared with the register storage-class specifier.

Given that the smallest addressability is a byte, and you may find your bitfileds compressed thus:

Addr\Bit   7   6   5   4   3   2   1   0
00001234 | a | b | c | d | ? | ? | ? | ? |
00001235 |   |   |   |   |   |   |   |   |

you can see that the address of all those bitfileds is actually the same, so it's not really that useful.

For manipulating bitfileds, you really should just access them directly and let the compiler sort them out. Even using bitwise operators isn't guaranteed to work unless you know how the compiler is laying them out in memory.

like image 8
paxdiablo Avatar answered Oct 12 '22 19:10

paxdiablo


Addresses must be an integer number of bytes, but bit-fields don't have to be, so the C standard specifies that the address operator & cannot be used with them. Of course, if you really want to do things with addresses of bitfields, you can just use the address of the enclosing structure, with some bitwise operations.

like image 5
1'' Avatar answered Oct 12 '22 19:10

1''