Ralf Baechle wrote:
struct foo { unsigned int x:1; unsigned int y:4; }; void bar(volatile struct foo *p) { p->x = 1; p->y++; } which gcc 4.3 for a MIPS32R2 target will compile into: lw $3, 0($4) li $2, 1 ins $3, $2, 31, 1 sw $3, 0($4) lw $2, 0($4) lw $3, 0($4) ext $2, $2, 27, 4 addiu $2, $2, 1 ins $3, $2, 27, 4 sw $3, 0($4) j $31 nop Imagine struct foo was describing a hardware register so the pointer to it was marked volatile. A human coder wouldn't have done multiple loads / stores. Worse, if you actually want to change multiple fields in a register atomically then with bitfields you have _no_ possibility to enforce that.
This is bogus as you use a false premise. For your test case the compiler is generating exactly the accesses you are requesting by declaring the thing as volatile.
The Linux programming programming model relies on accessor functions like readl, ioread32 etc. Those take addresses as arguments - but bitfields don't have addresses in C ...
We too use accessor functions, as they are required on certain classes of registers to obtain correct semantics.
The real question is if manipulating the values after they are obtained with the accessor is done correctly. My assertion is that although it may not be the One True Kernel Way, our structure bitfield definitions result in correct semantics and have better compile time error checking than can be obtained when coding a bunch of explicit masks and shifts.
That is not to say that I am adverse to eliminating the structure bitfield definitions, but we should not use incorrect register access semantics as the reason, as it is not a valid argument.
David Daney