16
votes

Following GCC __attribute__(packed ) will pack to byte boundary, aligned is used for which purpose :--

u8 rx_buf[14] __attribute__((aligned(8)));  
struct S { short f[3]; } __attribute__ ((aligned (8)));

above array will be of 16 byte, am I right.

means sizeof(rx_buff) will be 16 byte .. i.e 2 byte alignment at end

2
To answer your unasked question: no, you should not (and it is considered a bad practice) dump structures to disk or rely on memory alignment whatsoever, whether it is for internal program use or not.Dariusz

2 Answers

31
votes

The answer to your question is no. The aligned attribute does not change the sizes of variables it is applied to, but the situation is slightly different for structure members. To quote the manual,

aligned (alignment)

This attribute specifies a minimum alignment for the variable or structure field, measured in bytes. For example, the declaration:

int x __attribute__ ((aligned (16))) = 0;

causes the compiler to allocate the global variable x on a 16-byte boundary.

and,

packed

The packed attribute specifies that a variable or structure field should have the smallest possible alignment — one byte for a variable, and one bit for a field, unless you specify a larger value with the aligned attribute.

Here is a structure in which the field x is packed, so that it immediately follows a:

struct foo
{
    char a;
    int x[2] __attribute__ ((packed));
};

Note that the aligned attribute may change the memory layout of structures, by inserting padding between members. Subsequently, the size of the structure will change. For instance:

struct t {
    uint8_t  a __attribute__((aligned(16))); /* one byte plus 15 as padding here */
    uint16_t b __attribute__((aligned(16)));
};

would lead to 15 bytes of padding after a whereas the default alignment for the target architecture might have resulted in less. If you specified the packed attribute for the structure and lost the aligned attributes the structure would have a size of 3 bytes. Here's an illustration of how the memory layout of a structure might look like in each case.

struct t with no attributes and default alignment on 8-byte boundary:

+-+-------+--+-------+
|a|       |bb|       |
+-+-------+--+-------+

struct t when a and b are aligned on 16-byte boundaries:

+-+---------------+--+---------------+
|a|    padding    |bb|    padding    |
+-+---------------+--+---------------+

struct t when a and b have no alignment restrictions and t is packed:

+-+--+
|a|bb|
+-+--+
4
votes

above array will be of 16 byte, am I right.

Incorrect. The array is still 14 bytes long; all that __attribute__((aligned)) does is provide any necessary padding outside the array to align it to an 8-byte boundary. It is impossible to safely assume anything about where this padding exists, or how much of it there is.

As such, sizeof(rx_buf) will remain 14, just as it would have been without the alignment.