Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

array take size of struct in union

Tags:

arrays

c

struct

I have a union in a project i'm working on that represents a USB joystick report:

union {
    struct{
        uint8_t xaxis;
        uint8_t yaxis;
        uint8_t xraxis;
        uint8_t yraxis;
        uint8_t zraxis;
        uint8_t slider;

        uint8_t buttons8;
        uint8_t buttons16;
    };
    uchar buffer[8];
} report;

this way i can easily put the values into the struct members and use the buffer member to send that data over USB, however I end up modifying this union for different projects (different resolutions on the axis, more/less buttons etc) so then i have to work out what the new size of the struct is to declare the array with the same size.

is there a way to automatically make the array the same size? i thought of using sizeof which requires me to change the struct like this:

union {
    struct _data{ // either this
        uint8_t xaxis;
        uint8_t yaxis;
        uint8_t xraxis;
        uint8_t yraxis;
        uint8_t zraxis;
        uint8_t slider;

        uint8_t buttons8;
        uint8_t buttons16;
    } data; // or this
    uchar buffer[8];
} report;

but then i can no longer put data into the struct like this:

report.xaxis = value;

but instead:

report.data.xaxis = value;

which i don't want.

is there a way to do this cleanly?

like image 523
James Kent Avatar asked Sep 10 '25 13:09

James Kent


2 Answers

Step 1 is to get a standard C compiler. Then you can use an anonymous struct. To get the appropriate size for the array, use a struct tag, which is only needed internally by the union.

typedef union {
    struct data {
        uint8_t xaxis;
        uint8_t yaxis;
        uint8_t xraxis;
        uint8_t yraxis;
        uint8_t zraxis;
        uint8_t slider;
        uint8_t buttons8;
        uint8_t buttons16;
    }; 
    uint8_t buffer[sizeof(struct data)];
} report_t;

...

  report_t r; 
  r.xaxis = 123;
like image 76
Lundin Avatar answered Sep 13 '25 03:09

Lundin


You could use offsetof() for this with the last element in the struct

union
{
    struct data
    {
        uint8_t xaxis;
        uint8_t yaxis;
        uint8_t xraxis;
        uint8_t yraxis;
        uint8_t zraxis;
        uint8_t slider;

        uint8_t buttons8;
        uint8_t buttons16;
    };
    uint8_t buffer[offsetof(struct data, buttons16)+1];
} report;
like image 34
Serve Laurijssen Avatar answered Sep 13 '25 05:09

Serve Laurijssen