Zeyad Ibrahim
Zeyad Ibrahim

Reputation: 13

Comparison between structs in C using bitfields

So I really can't understand the difference between these two code segments. What I know about bit field is that I reserve in memory how many BITS I will use for this int. But why negative number appear in 2nd Struct?

#include<stdio.h>
#include<string.h>
typedef struct {
        unsigned int i:1;
        unsigned int k:31;
        int x;
}Struc1;
typedef struct{
        int i:1;
        int k:4;
        int x;
}Struc2;
int main()
{
        Struc1 s1={1,13,13};
        printf("%d %d %d\n",s1.i,s1.k,s1.x);
        Struc2 s2={1,13,13};
        printf("%d %d %d\n",s2.i,s2.k,s2.x);
        return 0;
}

OUTPUT:

1 13 13
-1 -3 13

Upvotes: 0

Views: 1492

Answers (3)

cdhaval
cdhaval

Reputation: 1

Your system is little endian so first bit is signed bit from right most bit that's why in your second struct you are inserting odd numbers so it takes first bit as signed bit and give a negative value.

 typedef struct{   
    int i:1;   //Here you inserting **1** so it will take as signed bit. 
    int k:4;   //Here you inserting odd value **13** so it will take negative
    int x;     //This is also signed but it is **32** bit so it has enough space to store your **13** integer value.
  }Struc2;

if you don't want negative value then give it as a unsigned or increase the bits allocation.Cheers..

Upvotes: 0

chux
chux

Reputation: 154255

This is a place in C where int, signed int may differ.

With bit-fields, An int without a signed or unsigned may be treated as signed int or unsigned int. Based on OP's reported output, this implementation defined behavior of int appears to be like signed int.

typedef struct{
  int i:1;  // like signed int i:1; for OP
  int k:4;  // like signed int k:4; for OP
  int x;
}Struc2;

The i bit-field likely has the range [-1...0] and k has [-8...7]. Initializing a signed integer via Struc2 s2={1,13,13}; with a value outside its range is implementation defined (Details: C11dr 6.3.1.3 3).

A common implementation defined behavior is to wrap around. So like Struc2 s2 = {1-2, 13-16, 13}; or Struc2 s2 = {-1, -3, 13};


When using bit-fields, recommend to use unsigned whenever possible. If int bit-fields are needed, use signed int.

Upvotes: 3

Achal
Achal

Reputation: 11921

Structure bit filed means reserving memory in terms of bits for data member of structure. While working on bit-field you should take care of sign bit if input is of signed type.

memory allocation for struc2 :

typedef struct{
        int i:1;
        int k:4;
        int x;
}Struc2;

1) For member i only one bits is reserved as

 -------
|  1    |
 -------
        i
        |
        this is only first and last bit

int i : 1 ; If there is no type mentioned for variable/constant then by default compiler will consider as signed type and if sign(MSB) bit of signed integer is 1 means it will be negative no. 2's complement of 1 is -1. so s2.i = -1

Note : In C, Negative no are stored in memory in form of two's complement

2) for member k, 4 bits are reserved (in that you are storing 13), it looks like below

       ---------------------------
13 => | 1   |    1   |  0   |  1  |
       ---------------------------
       0x103  0x102   0x101  0x100                      
        |
      sign bit

In this case also sign bit is 1 so s2.k will be negative and how much ? take two's complement(one's complement + 1).

        13 => 1101
           => 0010 (one's complement)
                +1
              -----
              0011 => 3  since sign bit was 1 so s2.k = -3
              -----    

Upvotes: 1

Related Questions