Next: Type Attributes, Previous: Character Escapes, Up: C Extensions
The keyword __attribute__
allows you to specify special
attributes of variables or structure fields. This keyword is followed
by an attribute specification inside double parentheses. Some
attributes are currently defined generically for variables.
Other attributes are defined for variables on particular target
systems. Other attributes are available for functions
(see Function Attributes) and for types (see Type Attributes).
Other front ends might define more attributes
(see Extensions to the C++ Language).
You may also specify attributes with `__' preceding and following
each keyword. This allows you to use them in header files without
being concerned about a possible macro of the same name. For example,
you may use __aligned__
instead of aligned
.
See Attribute Syntax, for details of the exact syntax for using attributes.
aligned (
alignment)
int x __attribute__ ((aligned (16))) = 0;
causes the compiler to allocate the global variable x
on a
16-byte boundary. On a 68040, this could be used in conjunction with
an asm
expression to access the move16
instruction which
requires 16-byte aligned operands.
You can also specify the alignment of structure fields. For example, to
create a double-word aligned int
pair, you could write:
struct foo { int x[2] __attribute__ ((aligned (8))); };
This is an alternative to creating a union with a double
member
that forces the union to be double-word aligned.
As in the preceding examples, you can explicitly specify the alignment (in bytes) that you wish the compiler to use for a given variable or structure field. Alternatively, you can leave out the alignment factor and just ask the compiler to align a variable or field to the default alignment for the target architecture you are compiling for. The default alignment is sufficient for all scalar types, but may not be enough for all vector types on a target which supports vector operations. The default alignment is fixed for a particular target ABI.
Gcc also provides a target specific macro __BIGGEST_ALIGNMENT__
,
which is the largest alignment ever used for any data type on the
target machine you are compiling for. For example, you could write:
short array[3] __attribute__ ((aligned (__BIGGEST_ALIGNMENT__)));
The compiler automatically sets the alignment for the declared
variable or field to __BIGGEST_ALIGNMENT__
. 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 or fields that you have
aligned this way. Note that the value of __BIGGEST_ALIGNMENT__
may change depending on command line options.
When used on a struct, or struct member, the aligned
attribute can
only increase the alignment; in order to decrease it, the packed
attribute must be specified as well. When used as part of a typedef, the
aligned
attribute can both increase and decrease alignment, and
specifying the packed
attribute will generate a warning.
Note that 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 your linker documentation for further information.
The aligned
attribute can also be used for functions
(see Function Attributes.)
cleanup (
cleanup_function)
cleanup
attribute runs a function when the variable goes
out of scope. This attribute can only be applied to auto function
scope variables; it may not be applied to parameters or variables
with static storage duration. The function must take one parameter,
a pointer to a type compatible with the variable. The return value
of the function (if any) is ignored.
If -fexceptions is enabled, then cleanup_function
will be run during the stack unwinding that happens during the
processing of the exception. Note that the cleanup
attribute
does not allow the exception to be caught, only to perform an action.
It is undefined what happens if cleanup_function does not
return normally.
common
nocommon
common
attribute requests GCC to place a variable in
“common” storage. The nocommon
attribute requests the
opposite—to allocate space for it directly.
These attributes override the default chosen by the
-fno-common and -fcommon flags respectively.
deprecated
deprecated (
msg)
deprecated
attribute results in a warning if the variable
is used anywhere in the source file. This is useful when identifying
variables that are expected to be removed in a future version of a
program. The warning also includes the location of the declaration
of the deprecated variable, to enable users to easily find further
information about why the variable is deprecated, or what they should
do instead. Note that the warning only occurs for uses:
extern int old_var __attribute__ ((deprecated)); extern int old_var; int new_fn () { return old_var; }
results in a warning on line 3 but not line 2. The optional msg argument, which must be a string, will be printed in the warning if present.
The deprecated
attribute can also be used for functions and
types (see Function Attributes, see Type Attributes.)
mode (
mode)
You may also specify a mode of `byte' or `__byte__' to
indicate the mode corresponding to a one-byte integer, `word' or
`__word__' for the mode of a one-word integer, and `pointer'
or `__pointer__' for the mode used to represent pointers.
packed
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: The 4.1, 4.2 and 4.3 series of GCC ignore the
packed
attribute on bit-fields of type char
. This has
been fixed in GCC 4.4 but the change can lead to differences in the
structure layout. See the documentation of
-Wpacked-bitfield-compat for more information.
section ("
section-name")
data
and bss
. Sometimes, however, you need additional sections,
or you need certain particular variables to appear in special sections,
for example to map to special hardware. The section
attribute specifies that a variable (or function) lives in a particular
section. For example, this small program uses several specific section names:
struct duart a __attribute__ ((section ("DUART_A"))) = { 0 }; struct duart b __attribute__ ((section ("DUART_B"))) = { 0 }; char stack[10000] __attribute__ ((section ("STACK"))) = { 0 }; int init_data __attribute__ ((section ("INITDATA"))); main() { /* Initialize stack pointer */ init_sp (stack + sizeof (stack)); /* Initialize initialized data */ memcpy (&init_data, &data, &edata - &data); /* Turn on the serial ports */ init_duart (&a); init_duart (&b); }
Use the section
attribute with
global variables and not local variables,
as shown in the example.
You may use the section
attribute with initialized or
uninitialized global variables but the linker requires
each object be defined once, with the exception that uninitialized
variables tentatively go in the common
(or bss
) section
and can be multiply “defined”. Using the section
attribute
will change what section the variable goes into and may cause the
linker to issue an error if an uninitialized variable has multiple
definitions. You can force a variable to be initialized with the
-fno-common flag or the nocommon
attribute.
Some file formats do not support arbitrary sections so the section
attribute is not available on all platforms.
If you need to map the entire contents of a module to a particular
section, consider using the facilities of the linker instead.
shared
shared
and marking the section
shareable:
int foo __attribute__((section ("shared"), shared)) = 0;
int
main()
{
/* Read and write foo. All running
copies see the same value. */
return 0;
}
You may only use the shared
attribute along with section
attribute with a fully initialized global definition because of the way
linkers work. See section
attribute for more information.
The shared
attribute is only available on Microsoft Windows.
tls_model ("
tls_model")
tls_model
attribute sets thread-local storage model
(see Thread-Local) of a particular __thread
variable,
overriding -ftls-model= command-line switch on a per-variable
basis.
The tls_model argument should be one of global-dynamic
,
local-dynamic
, initial-exec
or local-exec
.
Not all targets support this attribute.
unused
used
When applied to a static data member of a C++ class template, the
attribute also means that the member will be instantiated if the
class itself is instantiated.
vector_size (
bytes)
int foo __attribute__ ((vector_size (16)));
causes the compiler to set the mode for foo
, to be 16 bytes,
divided into int
sized units. Assuming a 32-bit int (a vector of
4 units of 4 bytes), the corresponding mode of foo
will be V4SI.
This attribute is only applicable to integral and float scalars, although arrays, pointers, and function return values are allowed in conjunction with this construct.
Aggregates with this attribute are invalid, even if they are of the same size as a corresponding scalar. For example, the declaration:
struct S { int a; }; struct S __attribute__ ((vector_size (16))) foo;
is invalid even if the size of the structure is the same as the size of
the int
.
selectany
selectany
attribute causes an initialized global variable to
have link-once semantics. When multiple definitions of the variable are
encountered by the linker, the first is selected and the remainder are
discarded. Following usage by the Microsoft compiler, the linker is told
not to warn about size or content differences of the multiple
definitions.
Although the primary usage of this attribute is for POD types, the attribute can also be applied to global C++ objects that are initialized by a constructor. In this case, the static initialization and destruction code for the object is emitted in each translation defining the object, but the calls to the constructor and destructor are protected by a link-once guard variable.
The selectany
attribute is only available on Microsoft Windows
targets. You can use __declspec (selectany)
as a synonym for
__attribute__ ((selectany))
for compatibility with other
compilers.
weak
weak
attribute is described in Function Attributes.
dllimport
dllimport
attribute is described in Function Attributes.
dllexport
dllexport
attribute is described in Function Attributes.
progmem
progmem
attribute is used on the AVR to place read-only
data in the non-volatile program memory (flash). The progmem
attribute accomplishes this by putting respective variables into a
section whose name starts with .progmem
.
This attribute works similar to the section
attribute
but adds additional checking. Notice that just like the
section
attribute, progmem
affects the location
of the data but not how this data is accessed.
In order to read data located with the progmem
attribute
(inline) assembler must be used.
/* Use custom macros from avr-libc */ #include <avr/pgmspace.h> /* Locate var in flash memory */ const int var[2] PROGMEM = { 1, 2 }; int read_var (int i) { /* Access var[] by accessor macro from avr/pgmspace.h */ return (int) pgm_read_word (& var[i]); }
AVR is a Harvard architecture processor and data and read-only data normally resides in the data memory (RAM).
See also the AVR Named Address Spaces section for an alternate way to locate and access data in flash memory.
Three attributes are currently defined for the Blackfin.
l1_data
l1_data_A
l1_data_B
l1_data
attribute will be put into the specific section
named .l1.data
. Those with l1_data_A
attribute will be put into
the specific section named .l1.data.A
. Those with l1_data_B
attribute will be put into the specific section named .l1.data.B
.
l2
l2
attribute will be put into the specific section
named .l2.data
.
One attribute is currently defined for the M32R/D.
model (
model-name)
small
, medium
,
or large
, representing each of the code models.
Small model objects live in the lower 16MB of memory (so that their
addresses can be loaded with the ld24
instruction).
Medium and large model objects may live anywhere in the 32-bit address space
(the compiler will generate seth/add3
instructions to load their
addresses).
The MeP target has a number of addressing modes and busses. The
near
space spans the standard memory space's first 16 megabytes
(24 bits). The far
space spans the entire 32-bit memory space.
The based
space is a 128 byte region in the memory space which
is addressed relative to the $tp
register. The tiny
space is a 65536 byte region relative to the $gp
register. In
addition to these memory regions, the MeP target has a separate 16-bit
control bus which is specified with cb
attributes.
based
based
attribute will be assigned to the
.based
section, and will be accessed with relative to the
$tp
register.
tiny
tiny
attribute assigned variables to the
.tiny
section, relative to the $gp
register.
near
near
attribute are assumed to have addresses
that fit in a 24-bit addressing mode. This is the default for large
variables (-mtiny=4
is the default) but this attribute can
override -mtiny=
for small variables, or override -ml
.
far
far
attribute are addressed using a full
32-bit address. Since this covers the entire memory space, this
allows modules to make no assumptions about where variables might be
stored.
io
io (
addr)
io
attribute are used to address
memory-mapped peripherals. If an address is specified, the variable
is assigned that address, else it is not assigned an address (it is
assumed some other module will assign an address). Example:
int timer_count __attribute__((io(0x123)));
cb
cb (
addr)
cb
attribute are used to access the control
bus, using special instructions. addr
indicates the control bus
address. Example:
int cpu_clock __attribute__((cb(0x123)));
Two attributes are currently defined for i386 configurations:
ms_struct
and gcc_struct
ms_struct
gcc_struct
packed
is used on a structure, or if bit-fields are used
it may be that the Microsoft ABI packs them differently
than GCC would normally pack them. Particularly when moving packed
data between functions compiled with GCC and the native Microsoft compiler
(either via function call or as data in a file), it may be necessary to access
either format.
Currently -m[no-]ms-bitfields is provided for the Microsoft Windows X86 compilers to match the native Microsoft compiler.
The Microsoft structure layout algorithm is fairly simple with the exception of the bitfield packing:
The padding and alignment of members of structures and whether a bit field can straddle a storage-unit boundary
offset % alignment-requirement == 0
Handling of zero-length bitfields:
MSVC interprets zero-length bitfields in the following ways:
For example:
struct { unsigned long bf_1 : 12; unsigned long : 0; unsigned long bf_2 : 12; } t1;
The size of t1
would be 8 bytes with the zero-length bitfield. If the
zero-length bitfield were removed, t1
's size would be 4 bytes.
foo
, and the
alignment of the zero-length bitfield is greater than the member that follows it,
bar
, bar
will be aligned as the type of the zero-length bitfield.
For example:
struct { char foo : 4; short : 0; char bar; } t2; struct { char foo : 4; short : 0; double bar; } t3;
For t2
, bar
will be placed at offset 2, rather than offset 1.
Accordingly, the size of t2
will be 4. For t3
, the zero-length
bitfield will not affect the alignment of bar
or, as a result, the size
of the structure.
Taking this into account, it is important to note the following:
t2
has a size of 4 bytes, since the zero-length bitfield follows a
normal bitfield, and is of type short.
struct { char foo : 6; long : 0; } t4;
Here, t4
will take up 4 bytes.
struct { char foo; long : 0; char bar; } t5;
Here, t5
will take up 2 bytes.
Three attributes currently are defined for PowerPC configurations:
altivec
, ms_struct
and gcc_struct
.
For full documentation of the struct attributes please see the documentation in i386 Variable Attributes.
For documentation of altivec
attribute please see the
documentation in PowerPC Type Attributes.
The SPU supports the spu_vector
attribute for variables. For
documentation of this attribute please see the documentation in
SPU Type Attributes.
One attribute is currently defined for xstormy16 configurations:
below100
.
below100
below100
attribute (BELOW100
is
allowed also), GCC will place the variable in the first 0x100 bytes of
memory and use special opcodes to access it. Such variables will be
placed in either the .bss_below100
section or the
.data_below100
section.