Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Type casting struct to integer c++

Tags:

c++

struct

I have a design that requires values to be contained at certain bits inside of a 32 bit word. Example being bits 10-15 must hold value 9, with the remaining bits all being 0. So for simplicity/readability I created a struct that contains a broken down version of what is asked.

struct {
    int part1 : 10;
    int part2 : 6;
    int part3 : 16;
} word;

I can then set part2 to be equal to whatever value is requested, and set the other parts as 0.

word.part1 = 0; 
word.part2 = 9;
word.part3 = 0;

I now want to take that struct, and convert it into a single 32 bit integer. I do have it compiling by forcing the casting, but it does not seem like a very elegant or secure way of converting the data.

int x = *reinterpret_cast<int*>(&word);

If I try to cast it just as a normal reinterpret_cast<int>(word) I get the following error:

invalid cast from type 'ClassName::<anonymous struct>' to type 'int'

There must be a better way of doing this, I just can not figure it out. Thanks in advance!

Note: Must be done in c++ style casting, because of standards and whatnot... eye roll

like image 205
MZimmerman6 Avatar asked Sep 08 '14 23:09

MZimmerman6


3 Answers

union Ints {
  struct {
    int part1 : 10;
    int part2 : 6;
    int part3 : 16;
 } word;
 uint32_t another_way_to_access_word;
};

may help

like image 182
Dmitri Sosnik Avatar answered Oct 20 '22 16:10

Dmitri Sosnik


typedef struct word {
  uint32_t part1 : 10;
  uint32_t part2 : 6;
  uint32_t part3 : 16;

  operator int() const{
    return (part1 << 22) + (part2 << 16) + part3;
  }

  word& operator=(int i){
    this->set(i);
    return *this;
  }

  void set(int i){
    part1 = (0xFFFF0000 & i) >> 16;
    part2 = (0x0000FC00 & i) >> 10;
    part3 = (0x000003FF & i);
  }

  word(int i){
    this->set(i);
  }
} word;

That should do it.

struct word myword = 20;
struct word second_word(50);

myword = 10;
second_word.set(50);

int x = myword;
iny y = second_word;

Note: Compiled & checked.

like image 35
Lux Avatar answered Oct 20 '22 18:10

Lux


The attempt reinterpret_cast<int>(word) does not work because there is no conversion operator defined between your user-defined struct type and int.

You could add a conversion operator to your struct, or preferably IMHO a named function to do the conversion, e.g.:

struct {
    uint32_t part1 : 10;
    uint32_t part2 : 6;
    uint32_t part3 : 16;

    uint32_t get_all_parts() const
    {
         return (part1 << 22) + (part2 << 16) + part3;
    }
} word;

Note, I used unsigned ints as they have well-defined behaviour on left shifting.

like image 3
M.M Avatar answered Oct 20 '22 17:10

M.M