Rules:
5.5.a. Appropriate care shall be taken to prevent the compiler from inserting padding bytes within struct or union types used to communicate to or from a peripheral or over a bus or network to another processor.
5.5.b. Appropriate care shall be taken to prevent the compiler from altering the intended order of the bits within bit-fields.
Example:
typedef struct
{
uint16_t count; // offset 0
uint16_t max_count; // offset 2
uint16_t _unused; // offset 4
uint16_t enable : 2; // offset 6 bits 15-14
uint16_t b_interrupt : 1; // offset 6 bit 13
uint16_t _unused1 : 7; // offset 6 bits 12-6
uint16_t b_complete : 1; // offset 6 bit 5
uint16_t _unused2 : 4; // offset 6 bits 4-1
uint16_t b_periodic : 1; // offset 6 bit 0
} timer_reg_t;
// Preprocessor check of timer register layout byte count.
#if ((8 != sizeof(timer_reg_t))
# error “timer_reg_t struct size incorrect (expected 8 bytes)”
#endif
Reasoning: Owing to differences across processor families and loose definitions in the ISO C language standards, there is a tremendous amount of implementation- defined behavior in the area of structures and unions. Bit-fields, in particular, suffer from severe portability problems, including the lack of a standard bit ordering and no official support for the fixed-width integer types they so often call out to be used with. The methods available to check the layout of such data structures include static assertions or other compile-time checks as well as the use of preprocessor directives, e.g., to select one of two competing struct layouts based on the compiler.
Enforcement: These rules shall be enforced during code reviews.