title: thoughts on unions in C, with regards to MISRA
body: <p><a href="http://www.misra-c.com/Activities/MISRAC/tabid/160/Default.aspx" rel="noreferrer">Misra</a> says to ban all unions. I also know that deviations are allowed as long as they are discussed and documented thoroughly.</p>
  
  <p>We have a microcontroller and an external eeprom to store statistical data (event/error logging, parameter settings and whatnot).</p>
  
  <p>The eventlog consists of around 80+ event counters some being 8, 16 and 32 bits (all unsigned). The parameter storage consists of around 200 parameters, also mixed with 8, 16 and 32 bit values (unsigned).</p>
  
  <p>We are rewriting all code to be MISRA compliant and as these values were previously defined is as follows:</p>
  
  <pre><code>typedef struct
  {
    U16BIT eventLogVar1;
    U32BIT eventLogVar2;
    U8BIT  eventLogVar3;
    U8BIT  eventLogVar4;
    U32BIT eventLogVar5;
  } EVENT_LOG;
  
  typedef union
  {
    EVENT_LOG log;
    U8BIT     array[sizeof(EVENT_LOG)];
  } ELOG;
  
  ELOG log;
  </code></pre>
  
  <p>Now this is not really MISRA compliant. Same goes for the parameter log. However this is the most easiest way to read and write from the eeprom, because I just have to read/write through the array to read/write from the eeprom.</p>
  
  <p>We have a few other rules that we simply are not allowed to break. No global (extern) variables (through header files). All local variables, if needed should only be accessed through get/set functions.</p>
  
  <p>That implies that if we need to fully write out all these parameters that these each should get their own get/set functions for altering them throughout the application.</p>
  
  <p>On of the solutions that I've thought on was the following:</p>
  
  <pre><code>#ifdef EITHER
  enum
  {
      eventLogVar1 = 0; /* 00 */
      pad01;            /* 01 */
      eventLogVar2;     /* 02 */
      pad03;            /* 03 */
      pad04;            /* 04 */
      pad05;            /* 05 */
      eventLogVar3;     /* 06 */
      eventLogVar4;     /* 07 */
      eventLogVar5;     /* 08 */
      pad09;            /* 09 */
      pad10;            /* 10 */
      pad11;            /* 11 */
  }
  #else /* OR */
  #define eventLogVar1 0 /* 2 bytes */
  #define eventLogVar2 2 /* 4 bytes */
  #define eventLogVar3 6 /* 1 byte  */
  #define eventLogVar4 7 /* 1 byte  */
  #define eventLogVar5 8 /* 4 bytes */
  #endif
  #define eventLogLastLength 4
  
  U8BIT eventLog[eventLogVar5 + eventLogLastLength];
  
  U8BIT getU8BIT(U8BIT index){}
  U16BIT getU16BIT(U8BIT index){}
  U32BIT getU32BIT(U8BIT index){}
  
  void setU8BIT(U8BIT index, U8BIT val){}  
  void setU16BIT(U8BIT index, U16BIT val){}
  void setU32BIT(U8BIT index, U32BIT val){}
  </code></pre>
  
  <p>However, this poses a combersome refactoring if values are added or removed. It also means that values of type array can not be used (and there are a few) which can be altered by defines in length if more or less of a certain type of, e.g., sensors, are used.</p>
  
  <hr>
  
  <p>What are your thoughts on this specific problem. Would I/we be better off documenting our deviation from the MISRA-standard in this specific case and only use this deviation at this specific place or are there better solutions to this problem?</p>