Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cast char to a bit field entry of 4 bits

Tags:

c

casting

Hello guys I'm facing another problem, I'm working on single bits and extract data from ascii text. The problem is that the compiler gives me an error about the fact that casting a char (8 bits) to a 4 bit memory field may alter its value.

Obviously that's true but how could I overcome that error?

typedef struct {
struct {
    unsigned int type:        4;
    unsigned int uid:         8;
    unsigned int operation:   4; 
    unsigned int reg:         16;
}header;
char *arg_nm;
} OWL_request;

The complete error:

 error: conversion to 'unsigned char:4' from 'char' may alter its value [-Werror=conversion]

and this is the assignment

request.header.type = (char)(j[0]-65);

j is *char

What I have to do is to get rid of the error without altering compiler flags

like image 716
Cristofor Avatar asked Nov 26 '25 12:11

Cristofor


2 Answers

With gcc, you can get rid of the warning by masking the value to the number of bits in the bitfield you assign to, since type is 4 bits, you can do:

request.header.type = (unsigned)(j[0]-65) & 0xf;

(Note that you can find several good arguments as to why you should not use bitfields , see e.g. here , and instead use plain integers and bit twiddling as suggested by @LPs)

like image 98
nos Avatar answered Nov 28 '25 03:11

nos


You should avoid bitfield struct. Use a simple unsigned int and use bitwise operators to assign values:

#define HEADER_VALUE_MASK 0xFu
#define HEADER_VALUE_POS  0
#define HEADER_UID_MASK   0xFu
#define HEADER_UID_POS    4

uint32_t header;

header |= (value & HEADER_VALUE_MASK) << HEADER_VALUE_POS;    
header |= (uid & HEADER_UID_MASK) << HEADER_UID_POS;

An implementation like this take also care of endianness and aligments.

like image 41
LPs Avatar answered Nov 28 '25 04:11

LPs



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!