Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overflow in bit fields

can I trust that the C compiler does modulo 2^n each time I access a bit field? Or is there any compiler/optimisation where a code like the one below would not print out Overflow?

struct {
  uint8_t foo:2;
} G;

G.foo = 3;
G.foo++;

if(G.foo == 0) {
  printf("Overflow\n");
}

Thanks in Advance, Florian

like image 766
Florian Avatar asked Feb 05 '11 17:02

Florian


People also ask

Is array of bit fields allowed?

Arrays of bit fields, pointers to bit fields, and functions returning bit fields are not allowed. The optional declarator names the bit field. Bit fields can only be declared as part of a structure. The address-of operator (&) cannot be applied to bit-field components.

How bit fields are stored in memory?

Again, storage of bit fields in memory is done with a byte-by-byte, rather than bit-by-bit, transfer.

What are bit fields explain their significance?

Bit fields can be used to reduce memory consumption when a program requires a number of integer variables which always will have low values. For example, in many systems storing an integer value requires two bytes (16-bits) of memory; sometimes the values to be stored actually need only one or two bits.

Can we set bit field for float?

You cannot store a float value in a bit-field structure. Floats have to adhere to a specific standard (IEEE 754) that specifies a representation. These representations are for 32 and 64 bits on x86. Therefore a bit field wouldn't have the necessary space to properly represent a floating point value..


2 Answers

Yes, you can trust the C compiler to do the right thing here, as long as the bit field is declared with an unsigned type, which you have with uint8_t. From the C99 standard §6.2.6.1/3:

Values stored in unsigned bit-fields and objects of type unsigned char shall be represented using a pure binary notation.40)

From §6.7.2.1/9:

A bit-field is interpreted as a signed or unsigned integer type consisting of the specified number of bits.104) If the value 0 or 1 is stored into a nonzero-width bit-field of type _Bool, the value of the bit-field shall compare equal to the value stored.

And from §6.2.5/9 (emphasis mine):

The range of nonnegative values of a signed integer type is a subrange of the corresponding unsigned integer type, and the representation of the same value in each type is the same.31)A computation involving unsigned operands can never overflow, because a result that cannot be represented by the resulting unsigned integer type is reduced modulo the number that is one greater than the largest value that can be represented by the resulting type.

So yes, you can be sure that any standards-conforming compiler will have G.foo overflow to 0 without any other unwanted side effects.

like image 79
Adam Rosenfield Avatar answered Oct 04 '22 04:10

Adam Rosenfield


No. The compiler allocates 2 bits to the field, and incrementing 3 results in 100b, which when placed in two bits results in 0.

like image 26
Ignacio Vazquez-Abrams Avatar answered Oct 04 '22 06:10

Ignacio Vazquez-Abrams