1

I am essentially trying to use a union to cast a structure of data pieces with varying bit-widths into a nice clean array of integers. I have written a small program to illustrate my issue.

#include <stdio.h>
#include <iostream.h>

union {
  struct {
    long blah1;
    short blah2;
    long blah3;
    short blah4;
    int blah5;
  } data;
  int buffer[6];
} db;

int main(int argc, char* argv)
{
  db.data.blah1 = 0x1111111111111111;
  db.data.blah2 = 0x2222;
  db.data.blah3 = 0x3333333333333333;
  db.data.blah4 = 0x4444;
  db.data.blah5 = 0x55555555;

  for(int i=0;i<6;i++) cout << "Word " << i << ": " << std::hex << db.buffer[i] << endl;  
}

Output:

Word 0: 11111111
Word 1: 11111111
Word 2: 2222
Word 3: 0
Word 4: 33333333
Word 5: 33333333

Expected Output:

Word 0: 11111111
Word 1: 11111111
Word 2: 33332222
Word 3: 33333333
Word 4: 44443333
Word 5: 55555555

I compiled using gcc version 4.1.2 20080704 (Red Hat 4.1.2-54)

Do I have something formatted incorrectly or am I trying to use this functionality for something other than it was intended? Is there another way to achieve my expected output without having to use bit-wise manipulation and endless shifting?

Yu Hao
  • 119,891
  • 44
  • 235
  • 294

1 Answers1

0

As pointed out by @happydave and Floris, result could be achieved by using pragma pack with value 1 to stop padding introduced for bit alignment.

#include <stdio.h>
#include <iostream>

using namespace std;

#pragma pack(push,1)
union {
  struct {
    long blah1;
    short blah2;
    long blah3;
    short blah4;
    int blah5;
  } data;
  int buffer[6];
} db;
#pragma pack(pop)

int main(int argc, char** argv)
{
  db.data.blah1 = 0x1111111111111111;
  db.data.blah2 = 0x2222;
  db.data.blah3 = 0x3333333333333333;
  db.data.blah4 = 0x4444;
  db.data.blah5 = 0x55555555;

  for(int i=0;i<6;i++) cout << "Word " << i << ": " << std::hex << db.buffer[i] << endl;  
}
Nik
  • 1,294
  • 10
  • 16