On Fri, Jan 20, 2017 at 09:45:07AM -0800, will sanfilippo wrote:
> I was referring to C code that accesses a packed structure, not necessarily 
> the construction part of it. For example: (and in this example I am assuming 
> the processor can access bytes anywhere, 16-bit values on 16-bit boundaries 
> and 32-bit values on 32-bit boundaries).
> 
> struct my_struct
> {
>       uint8_t e8;
>       uint16_t e16;
>       uint32_t e32;
> } __packed__          /* I know this syntax is wrong, just an example */
> struct my_struct my_data
> 
> In your C code when you do this: my_data.e32 = 50, what is the
> compiler going to do? If the structure is not packed, it knows it can
> use an instruction that accesses words. If the structure is packed,
> well, I guess it is up to the compiler what to do. In the past, I have
> seen compilers that add code or call functions that will check the
> alignment of e32. If e32 happens to reside on a 4-byte boundary it
> will use a word instruction; if it happens to reside on a byte
> boundary it needs to access the bytes individually to put them in a
> register for use.

I'm not really adding anything here, but here is something I realized
recently.  When you tell gcc to pack a struct, it has two effects:

    1. Eliminates padding.
    2. Assumes instances of the struct are not properly aligned.

For MCUs which don't support unaligned accesses, the second effect may
carry some hidden costs.  Even if the struct is defined such that it
wouldn't contain any padding, and even if all instances of the struct
are properly aligned, adding the __packed__ attribute will result in an
increase in code size.  The increase occurs because gcc can no longer
assume that the struct or any of its members are aligned.

Chris

Reply via email to