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.
struct S { short f[3]; } __attribute__
((aligned (8)));
typedef int more_aligned_int __attribute__
((aligned (8)));
-
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.
-
Note:
The alignment of any given
struct
or union
type is required by the ANSI C standard to be at least a perfect multiple
of the lowest common multiple of the alignments of all of the members of
the struct
or union
in question. This means that you can effectively adjust the alignment of
a struct
or union
type by attaching an aligned
attribute to any one of the members of such a type, but the notation illustrated
in the last example is a more obvious, intuitive, and readable way to request
the compiler to adjust the alignment of an entire struct
or union
type.
-
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:
struct S { short f[3]; } __attribute__ ((aligned));
-
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.
-
Note:
Although you can ask the
compiler to select a time-efficient alignment for a given type and then
declare only individual stand-alone objects of that type, the compiler’s
ability to select a time-efficient alignment is primarily useful only when
you plan to create arrays of variables having the relevant (efficiently
aligned) type. If you declare or use arrays of variables of an efficiently-aligned
type, then it is likely that your program will also be doing pointer arithmetic
(or subscripting, which amounts to the same thing) on pointers to the relevant
type, and the code that the compiler generates for these pointer arithmetic
operations will often be more efficient for efficiently-aligned types than
for other types.
-
The aligned
attribute can only increase the alignment; but you can decrease it by specifying
packed
as well. See the following discussion for packed.
-
Note:
The effectiveness of aligned
attributes may be limited by inherent limitations in your linker. On many
systems, the linker is only able to arrange for variables to be aligned
up to a certain maximum alignment. (For some linkers, the maximum supported
alignment may be very very small.) If your linker is only able to align
variables up to a maximum of 8 byte alignment, then specifying aligned(16)
in an __attribute__
will still only provide you with 8 byte alignment. See Specifying
attributes of variables, and see Linker
scripts and Using LD
in GNUPro Utilities for further information.
-
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 also specify attributes
between the enum,
struct
or union
tag and the name of the type rather than after the closing brace.
-
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:
typedef union
{
int *__ip;
union wait *__up;
} wait_status_pointer_t __attribute__ \
((__transparent_union__));
pid_t wait (wait_status_pointer_t);
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:
int w1 () { int w; return wait (&w); }
int w2 () { union wait w; return wait (&w); }
With this interface, the
wait
implementation might look like the following example’s input.
pid_t wait (wait_status_pointer_t p)
{
return waitpid (-1, p.__ip, 0);
}
-
unused
When attached to a type
(including a union
or a struct),
this attribute means that variables of that type are meant to appear possibly
unused. GNU CC will not produce a warning for any variables of that type,
even if the variable appears to do nothing. This is often the case with
lock or thread classes, which are usually de ned and then not referenced,
but contain constructors and destructors that have nontrivial bookkeeping
functions.
To specify multiple attributes,
separate them by commas within the double parentheses; for example,
__attribute__ ((aligned (16), packed))
Top|Contents|Index|Previous|Next