c - cannot take address of bit-field

夙愿已清 提交于 2019-11-30 23:11:30

问题


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

回答1:


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.




回答2:


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.




回答3:


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.




回答4:


You can't print the address of the bit field but you can assigned to some local variable of required size type(typecasting from one bit memory to 2 bytes(for integer type size will be compiler dependent) memory),that can be used for printing the address.

unsigned int x=pipe.a; printf("x=%d",&x);




回答5:


on a similar note, if you just want to address individual bytes, you could do something like this:

union PAIR  {
    struct { uint8_t l, h; } b;
    uint16_t w;
};

PAIR ax;

you can now access pointers to the pieces like &ax.w, &ax.b.l or &ax.b.h note that this still dont allow you to point to individual bits, see previous explanations about this.

EDIT: fixed example



来源:https://stackoverflow.com/questions/13547352/c-cannot-take-address-of-bit-field

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!