Re: How to make this union a struct instead?

Only thing I can think of is to make a reference variable to the inside struct.

typedef struct ControllerStruct_t{
  uint16_t checkBytes;
  uint16_t buttonState;
  uint8_t leftTrigger;
  uint8_t rightTrigger;
  int16_t leftHatX;
  int16_t leftHatY;
  int16_t rightHatX;
  int16_t rightHatY;
};

union ControllerUnion {
  uint8_t rawBuffer[14];
  ControllerStruct_t values;
} controller;

ControllerStruct_t &conValues = controller.values;

My question would be why you embed the struct in a union? Copying a struct can be done with memcpy and byte pointers.

Delta_G:
But I want to be able to load that buffer with a single memory copy and then get the values at will without having to do any extra bitmath

septillion:
...

I guess that is directed at my reply. I edited my reply before you posted the new one :wink:

Something in the line of

struct MYSTRUCT
{
...
...
};

MYSTRUCT s1;
MYSTRUCT s2;

// copy s1 to s2
memcpy((byte*)&S2, (byte*)&S1, sizeof(MYSRUCT));

And reading the man page for memcpy, the cast is not even needed.

How about using a zero sized byte array as first member of the struct?

struct Controller  {
  uint8_t rawBuffer[0];
  uint16_t checkBytes;
  uint16_t buttonState;
  uint8_t leftTrigger;
  uint8_t rightTrigger;
  int16_t leftHatX;
  int16_t leftHatY;
  int16_t rightHatX;
  int16_t rightHatY;
} values;

Instead of sizeof(rawBuffer) you obviously should use sizeof(Controller)...

You can use an anonymous struct:

union ControllerUnion {
    uint8_t rawBuffer[14];
    struct {
      ... 
    };    
};

This is standard C11, and GCC supports this as an extension for C++ and older C versions.

@sterretje, it's not about copying the struct as a whole but being able to dump a 14 bytes array of raw data in and read it back as separate variables.

I think oqibidipo nailed it, forgot you could do that. And Whandall as well although I would have never thought the compiler would allow me to me an array with size 0 :stuck_out_tongue:

But now I think about it, you could also treat it as a uint8_t array. Skip the union (and make controller only the struct) and do ((uint8_t*)&controller)[8] = 33. But I think the solutions of oqibidipo and Whandall are far prettier :stuck_out_tongue:

Delta_G:
The syntax for this is bulky though, I have to use 2 dots.

Meh. So what? Use a #define

#define foov foo.values

struct Controller foo;

septillion:
@sterretje, it's not about copying the struct as a whole but being able to dump a 14 bytes array of raw data in and read it back as separate variables.

I still don't get it. Make S1 an array of bytes and use memcpy. Or if this is e.g. a serial read, cast S2 to a byte pointer and read the data into the successive locations.

Yeah, if you can memcopy you can indeed, like I did, take the pointer of the struct. But if you want to fill it as an array the syntax gets ugly.

And yes, you could use a macro but
a) There are, as shown options without it which are safer so I would prefer them
b) It doesn't scale

@Delta_G, both options leave you with the same :slight_smile: Although I'm still very surprised you're allowed to make zero size arrays :smiley: