Contents|Index|Previous|Next

Specifying Attributes of Types

The keyword __attribute__ allows you to specify special attributes of struct and union types when you define such types. This keyword is followed by an attribute specification inside double parentheses. Three attributes are currently defined for types: aligned, packed, and transparent_union. Other attributes are defined for functions (see Declaring Attributes of Functions) and for variables (see Specifying Attributes of Variables).

You may also specify any one of these attributes with ‘__’ preceding and following its keyword. This allows you to use these attributes in header files without being concerned about a possible macro of the same name. For example, you may use __aligned__ instead of aligned.

You may specify the aligned and transparent_union attributes either in a typedef declaration or just past the closing curly brace of a complete enum, struct or union type definition and the packed attribute only past the closing brace of a definition.

aligned (alignment)   
This attribute specifies a minimum alignment (in bytes) for variables of the specified type. For example, the following declarations force the compiler to insure (as fast as it can) that each variable whose type is struct S or more_aligned_int will be allocated and aligned at least on an 8-byte boundary.
On a Sparc, having all variables of type, struct S, aligned to 8-byte boundaries allows the compiler to use the ldd and std (doubleword load and store) instructions when copying one variable of type, struct S, to another, thus improving run-time efficiency.
As in the preceding example, you can explicitly specify the alignment (in bytes) that you wish the compiler to use for a given struct or union type. Alternatively, you can leave out the alignment factor and just ask the compiler to align a type to the maximum useful alignment for the target machine you are compiling for. For example, you could write:
Whenever you leave out the alignment factor in an aligned attribute specification, the compiler automatically sets the alignment for the type to the largest alignment which is ever used for any data type on the target machine you are compiling for. Doing this can often make copy operations more efficient, because the compiler can use whatever instructions copy the biggest chunks of memory when performing copies to or from the variables which have types that you have aligned this way. In the example above, if the size of each short is 2 bytes, then the size of the entire struct S type is 6 bytes. The smallest power of two which is greater than or equal to that is 8, so the compiler sets the alignment for the entire struct S type to 8 bytes.
The aligned attribute can only increase the alignment; but you can decrease it by specifying packed as well. See the following discussion for packed.
packed
This attribute, attached to an
enum, struct,or union type definition, specified that the minimum required memory be used to represent the type.
Specifying this attribute for struct and union types is equivalent to specifying the packed attribute on each of the structure or union members. Specifying the ‘-fshort-enums’ flag on the line is equivalent to specifying the packed attribute on all enum definitions.
You may only specify this attribute after a closing curly brace on an enum definition, not in a typedef declaration, unless that declaration also contains the definition of the enum.
transparent_union
This attribute, attached to a union type definition, indicates that any function parameter having that union type causes calls to that function to be treated in a special way.
First, the argument corresponding to a transparent union type can be of any type in the union; no cast is required. Also, if the union contains a pointer type, the corresponding argument can be a null pointer constant or a void pointer expression; and if the union contains a void pointer type, the corresponding argument can be any pointer expression. If the union member type is a pointer, qualifiers like const on the referenced type must be respected, just as with normal pointer conversions.
Second, the argument is passed to the function using the calling conventions of first member of the transparent union, not the calling conventions of the union itself. All members of the union must have the same machine representation; this is necessary for this argument passing to work properly.
Transparent unions are designed for library functions that have multiple interfaces for compatibility reasons. For example, suppose the wait function must accept either a value of type int * to comply with Posix, or a value of type ‘union wait *’ to comply with the 4.1BSD interface. If  the wait function’s parameter were ‘void *’, wait would accept both kinds of arguments, but it would also accept any other pointer type and this would make argument type checking less useful. Instead, <sys/wait.h> might define the interface as follows:

This interface allows either ‘int *’ or ‘union wait *’ arguments to be passed, using the int *’ calling convention. The program can call wait with arguments of either type:

With this interface,  the wait implementation might look like the following example’s input.

To specify multiple attributes, separate them by commas within the double parentheses; for example,