views:

127

answers:

4

Can bitfields be used in union?

A: 

Yes it is possible, but I would recommend against it. The length and packing of bitfields is not portable. The size of the union will be difficult to predict (see here). There is a certain amount of complexity that you introduce into the code when you use unions or bitfields. While this complexity may be acceptable in your code, combining the two may result in an unacceptable amount of complexity. If you are using unions, structs and bitfields, you run into problems with memory alignment.

If this is throwaway code that only needs to be built and run on one machine, then it's probably fine. However, if you are checking this into version control where it will live on forever, I recommend against it.

If you give an example of why you want to do this, I or someone else can suggest a better alternative.

EDIT: clarified based on comments and to ask for feedback.

Ben Gartner
What's not portable about bit-fields in unions compared to just bit-fields in general? What specifically is going to be difficult to predict?
AndreyT
The complaint in the post you linked was about the sizeof() a union containing a bitfield, not the behavior. Struct size is always implementation-dependent and that had nothing to do with the bitfield. There was also a complaint about not being able to take the address of a bitfield member, but that's just how bitfields work and has nothing to do with the union.
Alan
Updated to be less vague. In general I am hyperparanoid about size/memory alignment because I work on firmware for microcontrollers. Unaligned structs or variables affect performance and can result in nonatomic loads and stores. Your mileage may vary.
Ben Gartner
@Ben Gartner: But that basically means that you don't like bit-fields in general. Not immediately related to the original question.
AndreyT
@AndreyT Mostly, yes. I do think the union compounds the problem because each member of the union contributes to the complexity of how the size of the union is determined. I am reading into it a little because I've seen this used in the case where you are mapping a protocol onto a c-struct, and mispredicting alignment will cause bugs. Is there still part of my answer after the edit that you think is vague or misleading?
Ben Gartner
+4  A: 

Yes, they can be. Why not? Bit-fields in unions behave in the same way they behave anywhere else. There's nothing special about bit-fields in unions (or unions with bit-fields).

AndreyT
+1  A: 

It's only unsafe if you write to one union element and read from a different one. If the details of your implementation ensure that does not happen, then a union containing a bitfied (and presumably other members) has well defined, safe behavior.

Alan
Isn't union type punning implementation defined?
detly
A: 

If you think about how union works, you have the answer, which is yes, of course (why not)? As we expect, the union is big enough to hold the largest datum, and so automatically the smaller. Bitfields are packed into "containers" and the compiler must be able to evaluate their final real size. The following shows some interesting facts (and of course is a wrong usage of a union, but not for the bitfield presence!)

#include <stdio.h>

union test {
  int a:5;
  int b:12;
  float c;
  double d;
  int x;
};

int main()
{
  union test x;
  printf("%d\n", sizeof(x));
  x.a = 31;
  printf("%d\n", x.a);
  printf("%d\n", x.b);
  x.c = 1.23;
  printf("%d\n", x.a);
  printf("%f\n", x.c);
  x.x = 31;
  printf("%d\n", x.x);
  printf("%d\n", x.a);
  printf("%d\n", x.b);
}
ShinTakezou