Reputation: 307
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;
}
Upvotes: 25
Views: 38492
Reputation: 2341
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.
Upvotes: -1
Reputation: 1
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);
Upvotes: 0
Reputation: 882156
You cannot actually have the address of a bit field because the smallest addressable unit in C is a byte (remembering that bytes in C are not necessarily 8 bits wide).
The best you could hope for is the address of the containing set of bytes.
The relevant part of the standard (C11 in this case) is section 6.5.3.2 Address and indirection operators
(my emphasis):
The operand of the unary
&
operator shall be either a function designator, the result of a[]
or unary*
operator, or anlvalue
that designates an object that is not a bit-field and is not declared with the register storage-class specifier.
Given that the unit of addressing is a byte, you may find your bit fields stored as (for example):
Bit 7 6 5 4 3 2 1 0
+---+---+---+---+---+---+---+---+
Address: 1234 | a | b | c | d | ? | ? | ? | ? |
+---+---+---+---+---+---+---+---+
1235 | | | | | | | | |
+---+---+---+---+---+---+---+---+
You can see that the address of all those bit fields is actually the same (1234), so it's not really that useful for distinguishing them..
For manipulating bit fields, you really should just access them directly and let the compiler sort it out.
Even using bit-wise operators isn't guaranteed to work unless you know how the compiler is laying them out in memory.
Upvotes: 10
Reputation: 126877
Bitfields members are (typically) smaller than the granularity allowed by pointers, which is the granularity of char
s (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.
Upvotes: 43
Reputation: 27115
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.
Upvotes: 6