The C standard forbids the reordering of this struct like mentioned here and here.

Alignment means that the address of a variable starts at a memory location which is divisible by the size of the variable. So if you take a32BitUInt for example which is of type uint32_t this variable can be located at addresses which are equal to n * 4 because the size of the variable is 4 bytes.

Now what will happen in our case? The compiler will look at the variables in the struct and determine the largest size used which will be aDouble in this case. The compiler will put the struct at a memory location which is aligned to the size of the largest variable (address = n * 8, because sizeof(myStruct.aDouble) = 8).

The compiler isn't allowed to change the order of the variables in memory so aChar will have the lowest address. Lets assume the address for aChar was 0. The next possible address would be 1 but this is not aligned for double numbers so aDouble will be stored at address 8 because this address is divisable by sizeof(myStruct.aDouble) = 8.

a32BitUInt has a size of 4 bytes and the next possible address is 16 so this is an aligned address. 20 would be the next possible address and this is also aligned for bool which has a size of 1.

The size of the struct has to be a multiple of the largest variable size. So taking our example the current size would be 21 (addresses 0 .. 20). 21 (current size of struct) divided by 8 (size of aDouble) = 2,625. This would result in the compiler to add some padding so that the size would be ceil(2,625) * 8 bytes = 3 * 8 bytes = 24 bytes.