Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

146
Views
Union fails to decode byte array

The following code fails to decode the latitude and longitude. The output is: 132, 1, 1645780273, 77276230, 0, -0.000000, 0.000000, doing a wrong conversion on the last 2 values latitude & longitude. If I remove the first 4 values and delete uint32_t identifiers; from the struct i get the correct result 132, 1, 1645780273, 77276230, 0, 59.877871, 10.465200

Any help in understanding this behavior ist very appreciated.

#include <stdio.h>
#include <string.h>
int main() {
    union  {
        unsigned char bytes[36];
        struct{
            uint32_t identifier;
            uint16_t telegram_size;
            uint16_t telegram_version;
            uint32_t seconds;
            uint32_t nanoseconds;
            uint32_t stat;
            double latitude;
            double longitude;
      }unpack;
    }telegram;

    unsigned char values[] = {0x23, 0x4B, 0x4D, 0x42, 0x84, 0x00, 0x01, 0x00, 0x31, 0x9d, 0x18, 0x62, 0x46, 0x24, 0x9b, 0x04, 0x00, 0x00, 0x00, 0x00, 0x9d, 0x3e, 0x2c, 0x11, 0x5e, 0xf0, 0x4d, 0x40, 0xCA, 0x32, 0xC4, 0xB1, 0x2E, 0xEE, 0x24, 0x40};
    memcpy(telegram.bytes, values, 36);

    for (int i=0;i<36;i++){
        printf("%02X ", telegram.bytes[i]);
    }
    printf("\n%u, %u, %u, %u, %u, %f, %f\n", telegram.unpack.telegram_size, telegram.unpack.telegram_version, telegram.unpack.seconds, telegram.unpack.nanoseconds, telegram.unpack.stat, telegram.unpack.latitude, telegram.unpack.longitude);
    return 0;
}

Update: As far as I understood from the comments below the struct looks like this: enter image description here

over 4 years ago · Santiago Trujillo
2 answers
Answer question

0

This has to do with struct padding.

Generally speaking, members of a struct start at an offset which is a multiple of that member's size for alignment purposes. Because of this, there are 4 padding bytes between the stat and latitude members so that the latter can reside at an offset that is a multiple of 8. That means the struct is 4 bytes larger than you think it is.

If you're able to, you should rearrange the members so that they align at a natural offset so that there is no padding between the members (although there may still be padding at the end).

If that's not an option, you can pack the struct using a compiler-specific attribute. If you're using gcc, you would do the following:

    struct __attribute__((__packed__)) {
        uint32_t identifier;
        uint16_t telegram_size;
        uint16_t telegram_version;
        uint32_t seconds;
        uint32_t nanoseconds;
        uint32_t stat;
        double latitude;
        double longitude;
  }unpack;

Note also that on some architectures, an unaligned read or write can cause a crash.

over 4 years ago · Santiago Trujillo Report

0

You are assuming that the structure is laid out with all members contiguous. That is not a safe assumption. Implementations are free to insert arbitrary padding into structure layouts between members and after the last member. In practice, they will do so in a manner that allows them to ensure that all members can be properly aligned in memory.

In your particular case, your 8-byte doubles want to be aligned on 8-byte boundaries. Your implementation is ensuring that they can be by putting them at offsets from the beginning of the structure that are multiples of 8 bytes. That involves inserting four bytes of otherwise unused padding between stat and latitude, which your initialization does not account for. The overall structure will also have an 8-byte alignment requirement, and its total size will be a multiple of 8 bytes.

Removing the four-byte initial member allows the two doubles to be aligned without any padding, which is why that variation on your program worked as you expected.

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!