SPRUIG8J January 2018 – March 2024
The following type attributes are supported:
Using the aligned type attribute causes the individual elements of a structure, union, or other type to be padded (as is usual for a struct) as needed to achieve the specified alignment for all elements. In addition, any derived types have the same alignment. For example:
struct __attribute__((aligned(32))) myStruct { char c1; int i; char c2; };
The packed attribute is supported for struct and union types. It is available only for target architectures that have hardware support for unaligned access if the --relaxed_ansi option is used.
Members of a packed structure are stored as closely to each other as possible, omitting additional bytes of padding usually added to preserve word-alignment. For example, assuming a word-size of 4 bytes ordinarily has 3 bytes of padding between members c1 and i, and another 3 bytes of trailing padding after member c2, leading to a total size of 12 bytes:
struct unpacked_struct { char c1; int i; char c2;};
However, the members of a packed struct are byte-aligned. Thus the following does not have any bytes of padding between or after members and totals 6 bytes:
struct __attribute__((__packed__)) packed_struct { char c1; int i; char c2; };
Subsequently, packed structures in an array are packed together without trailing padding between array elements.
Using "packed" on a bit-field overrides the EABI requirements for bit-fields. For non-packed bit-fields, the declared type of a bit-field is used for the container type. For packed bit-fields, the smallest integral type (except bool) is used, regardless of the declared type. For non-packed volatile bit-fields, the bit-field must be accessed using one access of the same size as the declared type. For packed volatile bit-fields, the access must be of the same size as the actual container type, and may not be the same as the declared type; additionally, the actual container might not be aligned, and might span more than one aligned container boundary, so accessing a packed volatile bit-field may require more than one memory access. This can also affect the overall size of the struct; for instance, if the struct contains only the bit-field, the struct might not be as large as the declared type of the bit-field. For both packed and unpacked bit-fields, bit-fields are bit-aligned and are packed together with adjacent bit-fields with no padding, are entirely contained within an integer container that is at least byte-aligned; and do not alter the alignment of adjacent non-bitfield struct members.
The "packed" attribute can be applied only to the original definition of a structure or union type. It cannot be applied with a typedef to a non-packed structure that has already been defined, nor can it be applied to the declaration of a struct or union object. Therefore, any given structure or union type can only be packed or non-packed, and all objects of that type will inherit its packed or non-packed attribute.
The "packed" attribute is not applied recursively to structure types that are contained within a packed structure. Thus, in the following example the member s retains the same internal layout as in the first example above. There is no padding between c and s, so s falls on an unaligned boundary:
struct __attribute__((__packed__)) outer_packed_struct { char c; struct unpacked_struct s; };
It is illegal to implicitly or explicitly cast the address of a packed struct member as a pointer to any non-packed type except an unsigned char. In the following example, p1, p2, and the call to foo are all illegal.
void foo(int *param);
struct packed_struct ps;
int *p1 = &ps.i;
int *p2 = (int *)&ps.i;
foo(&ps.i);
However, it is legal to explicitly cast the address of a packed struct member as a pointer to an unsigned char:
unsigned char *pc = (unsigned char *)&ps.i;
The TI compiler also supports an unpacked attribute for an enumeration type to allow you to indicate that the representation is to be an integer type that is no smaller than int; in other words, it is not packed.