Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is assigning a value to a bit field not giving the same value back?

I saw the below code in this Quora post:

#include <stdio.h>  struct mystruct { int enabled:1; }; int main() {   struct mystruct s;   s.enabled = 1;   if(s.enabled == 1)     printf("Is enabled\n"); // --> we think this to be printed   else     printf("Is disabled !!\n"); } 

In both C & C++, the output of the code is unexpected,

Is disabled !!

Though the "sign bit" related explanation is given in that post, I am unable to understand, how it is possible that we set something and then it doesn't reflect as it is.

Can someone give a more elaborate explanation?


Note: Both the tags c & c++ are required, because their standards slightly differ for describing the bit-fields. See answers for C specification and C++ specification.

like image 388
iammilind Avatar asked Dec 19 '18 14:12

iammilind


People also ask

What are the advantages and disadvantages with bit fields?

Disadvantages of bit-fieldsUsing bit-fields costs loss of portability, since word-size varies from machine to machine. We cannot take address of a bit-field. Bit-fields cannot be made arrays. Size of bit-fields cannot be taken (using sizeof() operator).

How does bit field work?

In programming terminology, a bit field is a data structure that allows the programmer to allocate memory to structures and unions in bits in order to utilize computer memory in an efficient manner. Since structures and unions are user-defined data types in C, the user has an idea of how much memory will they occupy.

What are the advantages with bit fields?

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 reference a bit field?

Pointers and non-const references to bit-fields are not possible.


1 Answers

Bit-fields are incredibly poorly defined by the standard. Given this code struct mystruct {int enabled:1;};, then we don't know:

  • How much space this occupies - if there are padding bits/bytes and where they are located in memory.
  • Where the bit is located in memory. Not defined and also depends on endianess.
  • Whether an int:n bitfield is to be regarded as signed or unsigned.

Regarding the last part, C17 6.7.2.1/10 says:

A bit-field is interpreted as having a signed or unsigned integer type consisting of the specified number of bits 125)

Non-normative note explaining the above:

125) As specified in 6.7.2 above, if the actual type specifier used is int or a typedef-name defined as int, then it is implementation-defined whether the bit-field is signed or unsigned.

In case the bitfield is to be regarded as signed int and you make a bit of size 1, then there is no room for data, only for the sign bit. This is the reason why your program might give weird results on some compilers.

Good practice:

  • Never use bit-fields for any purpose.
  • Avoid using signed int type for any form of bit manipulation.
like image 97
Lundin Avatar answered Sep 27 '22 19:09

Lundin