Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using C unions to "reserve" space in data - reasonable?

Sorry if the title is a bit skew, I couldn't think of a concise explanation of what I'm on about!

Anyway, we have an embedded system that stores its settings data in a small SPI EEPROM/Flash chip. In a very basic form it's a struct containing the settings data, a simplified version might look like:

struct settings_data
{
   struct factory_data
   { // Data set at the factory
      uint32 serial_number;
      uint32 calibration;
   };
   struct user_data
   { // User-configured data follows:
      uint8  user_data_1;
      uint8  user_data_2;
      char[10]  somestring;
      // etc...
   };
 }

All fine and dandy until we need to stick an extra value into _factory_data_, at which point everything after it moves.

Now, there are many ways to handle this, but this question is not about finding a different method, it's about whether this idea is reasonable to pad out the data structures so that they don't move when you add things:

struct settings_data
{
   union factory_union
   {
      uint8 padding[100]; // Effectively reserve 100 bytes space
      struct factory_data
      { // Data set at the factory
         uint32 serial_number;
         uint32 calibration;
      };
   };
   union user_union
   {
      uint8 padding[100]; // Effectively reserve 100 bytes space
      struct user_data
      { // User-configured data follows:
         uint8  user_data_1;
         uint8  user_data_2;
         char[10]  somestring;
         // etc...
      };
   };
 }

If I understand unions correctly, this will reserve 100 bytes storage in the settings_data structure, and any new members we add to the "real" data struct inside the union will not cause the union to grow unless we exceed 100 bytes.

The question is is this a reasonable way to achieve this, given that we have relatively limited resources?

like image 967
John U Avatar asked Feb 03 '26 07:02

John U


1 Answers

It is reasonable, but it is possible for the size of the union to change when your structure changes even if the structure is still smaller than the padding element.

As it is in your question, the union is likely 100 bytes. Suppose you add a double to the structure, which (we assume) requires eight-byte alignment. Then the compiler makes the union 104 bytes, so that its size will be a multiple of eight (which is necessary so that arrays of the union would maintain the required alignment).

You can avoid this by making the padding a multiple of the alignment requirement of all types you might add in the future.

like image 62
Eric Postpischil Avatar answered Feb 05 '26 02:02

Eric Postpischil



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!