James Kuyper
8/31/2011 9:56:00 PM
On 08/31/2011 05:23 PM, Quentin Pope wrote:
> On my compiler, the output of "sizeof(foo)" of the following is 8,
> instead of 4.
>
> Which indicates that the compiler is aligning the union at
> the next int boundary, rather than coalescing it with "proto".
>
> I think this is a bug.
>
>
> struct s_skip_ind {
> unsigned skip_ind:4;
> };
>
> struct s_trans_id {
> unsigned trans_val:3;
> unsigned trans_id:1;
> };
>
> struct foo {
> unsigned proto:4;
> union {
> s_skip_ind skip_ind;
> s_trans_id trans_id;
> };
Ian has already pointed out to you the syntax errors in that declaration.
> };
"An implementation may allocate any addressable storage unit large
enough to hold a bit-field. If enough space remains, a bit-field that
immediately follows another bit-field in a structure shall be packed
into adjacent bits of the same unit." (6.7.2.1p10)
However, the thing that follows proto is not another bit field, but a
union. The union contains two structs, both structs contain bit fields,
but those bit fields are not members of the same struct that proto is.
Therefore, 6.7.2.1p10 does not apply.
Here's an alternative approach that should cause the fields to be merged
into the same storage unit. However, there's no guarantees about what
size the "storage unit" is. It could have a size of 8.
struct s_skip_ind {
unsigned proto:4;
unsigned skip_ind:4;
};
struct s_trans_id {
unsigned proto:4;
unsigned trans_val:3;
unsigned trans_id:1;
};
union foo {
struct s_skip_ind skip_ind;
struct s_trans_id trans_id;
};
Note that, with this definition, both 'proto's are required to occupy
the same bits (6.5.2.3p5).