0

My module receives raw data, its type and length from a communication module. I want to map this raw data into a (packed) union to parse easily. Instead of casting each structure, I want to cast one big union.

typedef strcut
{
    unsigned char a;
} msg1_t;

typedef strcut
{
    char a[4];
    char b[16];
} msg2_t;

typedef strcut
{
    // int size;    // don't want this 
    char b[];       // this doesn't work, there must be more than 1 element
} flex_array_t;

typedef union
{
    msg1_t msg1;
    msg2_t msg2;
    int msg3;
    char msg4[16];
    char str[?];    // length is variable..
    char* str_ptr;  // now, pointer is in the union. not array
} msg_union_t;

My question is how should I add a string properly in an union without specifying its length (not possible)? What is the best practice for this?

char str[0] works with GCC but it is not in the C standard. It also works with a dummy size i.e. char str[1], char str[32] but then size is misleading. I have also tried having flexible array in a struct, but it requires more members.

I am using these like this:

void foo(some_enum_t data_type, const unsigned char* data, int data_length)
{
    const msg_union_t* msg = (msg_union_t*)data;
    // some checks for length etc..

    switch(data_type)
    {
    default: 
        break;

    case DataType_Msg1: 
        bar(&msg->msg1);    // pointer to a msg1_t
        break;

    case DataType_Str: 
        bar_str(msg->str);  // char array
        break;
    }
}

uffu
  • 43
  • 6
  • How would you like to determine the size of that array? – the busybee Jul 30 '20 at 10:53
  • it will be provided in data_len. – uffu Jul 30 '20 at 11:39
  • Then go with `char str[1]`, it's a common idiom. You can also add an explanatory comment. – the busybee Jul 30 '20 at 13:05
  • @thebusybee: Do gcc and clang offer any option to prohibit present and future versions from performing "clever" optimizations based on the fact that `str[i]` would only have defined behavior when `i` is zero? I don't think present versions would be that stupid^h^h^h^h^h^hclever, but there's no guarantee that future versions wouldn't regard such restraint as a "missed optimization". – supercat Jul 30 '21 at 21:39

0 Answers0