title: Overeager struct packing warnings with `__attribute__((packed))`?
body: <p>I'm implementing a binary logging system on a 32 bit ARM mcu (Atmel SAM4SD32C, a Cortex-M4/ARMv7E-M part), and in the process of designing my data structures. My goal is to describe the log format as a packed struct, and simply union the struct with a char array, for writing to the log device (a SD card, via FatFS, in this case).</p>
  
  <p>Basically, I have a very simple struct:</p>
  
  <pre><code>typedef struct adc_samples_t
  {
      int32_t adc_samples[6];
  
      uint64_t acq_time;
  
      int8_t  overrun;
      uint8_t padding_1;
      uint8_t padding_2;
      uint8_t padding_3;
  
  } __attribute__((packed, aligned(4))) adc_sample_set;
  </code></pre>
  
  <p>Now, my architecture is 32 bits, so as far as I understand, access to any member /other/ then the <code>overrun</code> member should be 32-bit aligned, and therefore not have an extra overhead. Furthermore, the <code>aligned(4)</code> attribute should force any instantiations of the struct to be on a 32-bit aligned boundary.</p>
  
  <p>However, compiling the above struct definition produces a pile of warnings:</p>
  
  <pre><code>        In file included from ../src/main.c:13:0:
  &lt;snip&gt;\src\fs\fs-logger.h(10,10): warning: packed attribute causes inefficient alignment for 'adc_samples' [-Wattributes]
            int32_t adc_samples[6];
                    ^
  &lt;snip&gt;\src\fs\fs-logger.h(12,11): warning: packed attribute causes inefficient alignment for 'acq_time' [-Wattributes]
            uint64_t acq_time;
  </code></pre>
  
  <p>As far as I know (and I'm now realizing this is a big assumption), I assumed that 32-bit alignment was all that was needed for optimal component positioning on 32 bit arm. <strike>Oddly, the only member that does /not/ produce warnings are the <code>overrun</code> and <code>padding_X</code> members, which I don't understand the causes for.</strike> (Ok, the <a href="http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0553a/BABFAIGG.html" rel="nofollow noreferrer">ARM docs</a> say <code>Byte accesses are always aligned.</code>)</p>
  
  <p>What, exactly, is going on here? I assume (possibly incorrectly) that the struct instantiation will be on 4 bytes boundaries. Does the compiler require a more broad alignment (on 8 byte boundaries)?</p>
  
  <hr>
  
  <p>Edit: Ok, digging into the ARM docs (the magic words here were "Cortex-M4 alignment":</p>
  
  <blockquote>
    <p>3.3.5. Address alignment</p>
    
    <p>An aligned access is an operation where a word-aligned address is used for a word, dual word, or multiple word access, or where a halfword-aligned address is used for a halfword access. Byte accesses are always aligned.</p>
    
    <p>The Cortex-M4 processor supports unaligned access only for the following instructions:</p>
    
    <p>LDR, LDRT<br>
    LDRH, LDRHT<br>
    LDRSH, LDRSHT<br>
    STR, STRT<br>
    STRH, STRHT  </p>
    
    <p>All other load and store instructions generate a UsageFault exception if they perform an unaligned access, and therefore their accesses must be address aligned. For more information about UsageFaults see Fault handling.</p>
    
    <p>Unaligned accesses are usually slower than aligned accesses. In addition, some memory regions might not support unaligned accesses. Therefore, ARM recommends that programmers ensure that accesses are aligned. To trap 
    accidental generation of unaligned accesses, use the UNALIGN_TRP bit in the Configuration and Control Register, see Configuration and Control Register.</p>
  </blockquote>
  
  <p>How is my 32-bit aligned value not word-aligned? The user guide defines "Aligned" as the following:</p>
  
  <blockquote>
    <p>Aligned<br>
    A data item stored at an address that is divisible by the
    number of bytes that defines the data size is said to be aligned.
    Aligned words and halfwords have addresses that are divisible by four
    and two respectively. The terms word-aligned and halfword-aligned
    therefore stipulate addresses that are divisible by four and two
    respectively.</p>
  </blockquote>