Search code examples
c++cembeddedesp32

Is it good practice to have a big structure that contains multiple objects of other structures?


I'm making a code in PlatformIO for ESP32, and I came across a way of making structures that I'm not sure would be advantageous for the microcontroller, but sure seems to make my life a lot easier. Here's an example:

struct Error 
{
    bool lowBattery;
    bool commTimeout;
};

struct User
{
    uint8_t id;
    bool theme;
    uint8_t pass[4];
};

struct Device
{
    User user;
    Error error;
    uint8_t taskCode;
    uint8_t taskName[20];
} device;

In this example, I'm making objects of User and Error in Device structure, and then making an object called device. This way, I'm able to manage all of my data through this singular object, and I can access all elements by device.error.lowVoltage, giving additional context when I'm building code around this structure. From what I've read about structures, this might make the total size of a single object very large, to the point that my microcontroller might not be able to handle it. This is an example; my use case will have even larger structures. So far, I've not come across any glaring issue, but it will a lot of unnecessary changes if I get an error related to this approach in the future.

So, am I being unnecessarily paranoid? What can go wrong with this approach? Is there another way I can make managing data easier?


Solution

  • From what I've read about structures, this might make the total size of a single object very large, to the point that my microcontroller might not be able to handle it.

    Unlikely, although optimizing structs for alignment in order to reduce padding is common practice during code review. In your specific example there isn't much to do since all members likely boil down to 1 byte types. In general you would try to keep things aligned with 32 bits.

    to the point that my microcontroller might not be able to handle it

    These ESP32 things they have huge RAM memory of some 320kib so I wouldn't worry about a few bytes here and there. If you somehow manage to run out of RAM despite that, then struct padding is probably the least of your problems. Just keep in mind not to allocate huge arrays or structs on the stack.

    What can go wrong with this approach?

    The only thing that can go from is if you attempt to serialize/deserialize these structs for sending over a serial bus etc, in which case you have to consider alignment and padding (and endianess).

    Is there another way I can make managing data easier?

    Focus on writing readable, maintainable code, with unambiguous type names and variable names. Device is for example a god-awfully poorly picked type name.

    It makes perfect sense to put data that belongs together in the same struct. It doesn't make sense to put unrelated data in the same struct. Common sense will get you very far here.