Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Reading Raw Bytes into a Padded Struct (C++)

I have an 18 byte struct in C++. I want to read 18 bytes of data from a file straight into this struct. However, my C++ compiler pads the struct to be 20 bytes (4 byte aligned). This is relatively easy to get around for just my compiler alone but I would prefer to use a method that is more reliable cross-platform/cross-compiler.

This is the struct:

struct Test {
    uint8_t a;
    uint8_t b;
    uint8_t c;
    uint16_t d;
    uint16_t e;
    uint8_t f;
    uint16_t g; 
    uint16_t h; 
    uint16_t i; 
    uint16_t j; 
    uint8_t  k;  
    uint8_t  l;
};

Currently I use an ifstream and read it to the struct like so:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Test test;
// file is a binary ifstream
file.read((char*)test.a, 18);

On my system this skips past the two bytes of padding at the beginning of the struct. I could add bytes to the front of the struct to guarantee it to be 32 bytes which would be a valid alignment on most systems, however I don’t know if that would actually work with how structs need their elements to be naturally aligned.

Any help on this would be great but I could always end up copying the bytes manually into the attributes 😔.

>Solution :

If you are writing for cross-platform and cross-compiler, forget the direct read. Just read byte-by-byte. If profiling indicates you need further optimization, either play with the underlying stream buffering or read into a byte array and extract each piece.

This also eliminates system endianness problems.

// extract byte values
t.a = f.get();
t.b = f.get();

...

// extract a little-endian value
t.d = f.get();
t.d = t.d | (f.get() << 8);

...

// check for success or failure
if (!f) ...

Block read via a byte array:

unsigned char buffer[ 18 ];
if (!f.read( (char *)buffer, sizeof(buffer) ))
  ...

t.a = buffer[0];
...
t.d = buffer[3] | (buffer[4] << 8);
...

Again, profile before deciding there is an issue.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading