8.11 Variable Attributes
The compiler keyword __attribute__
allows you to specify special attributes of variables or structure fields. This keyword is followed by an attribute specification inside double parentheses.
You may also specify attributes with __
(double underscore) preceding and following each keyword (e.g., __aligned __
instead of aligned
). This allows you to use them in header files without being concerned about a possible macro of the same name.
To specify multiple attributes, separate them by commas within the double parentheses, for example:
__attribute__ ((aligned (16), packed)).
extern
in file B without the same attribute, then a link error might result.address (addr)
Specify an absolute virtual address for the variable. This attribute can be used in conjunction with a section attribute.
This attribute can be used to start a group of variables at a specific address:
int foo __attribute__((section("mysection"),address(0xA0001000)));
int bar __attribute__((section("mysection")));
int baz __attribute__((section("mysection")));
Keep in mind that the compiler performs no error checking on the specified address. The section will be located at the specified address regardless of the memory-region ranges listed in the linker script or the actual ranges on the target device. This application code is responsible for ensuring that the address is valid for the target device and application.
In addition, to make effective use of absolute sections and the new best-fit allocator, standard program-memory and data-memory sections should not be mapped in the linker script. The built-in linker script does not map most standard sections such as the .text
, .data
, .bss
, or .ramfunc
section. By not mapping these sections in the linker script, we allow these sections to be allocated using the best-fit allocator rather than the sequential allocator. Sections that are unmapped in the linker script can flow around absolute sections whereas sections that are linker-script mapped are grouped together and allocated sequentially, potentially causing conflicts with absolute sections.
space(prog)
or space(data)
, respectively. Also, see the description for the space
attribute.aligned (n)
The attributed variable will be aligned on the next n
byte boundary.
The aligned
attribute can also be used on a structure member. Such a member will be aligned to the indicated boundary within the structure.
If the alignment value n
is omitted, the alignment of the variable is set 8 (the largest alignment value for a basic data type).
Note that the aligned
attribute is used to increase the alignment of a variable, not reduce it. To decrease the alignment value of a variable, use the packed
attribute.
cleanup (function)
Indicate a function to call when the attributed automatic function scope variable goes out of scope.
The indicated function should take a single parameter, a pointer to a type compatible with the attributed variable, and have void
return type.
externally_visible
This attribute when used with a global object ensures the object remains visible outside the current compilation unit. This might prevent certain optimizations from being performed on the object.
packed
The attributed variable or structure member will have the smallest possible alignment. That is, no alignment padding storage will be allocated for the declaration. Used in combination with the aligned
attribute, packed
can be used to set an arbitrary alignment restriction greater or lesser than the default alignment for the type of the variable or structure member.
persistent
This attribute prevents the startup code's data-initialization code from initializing the variable. This behavior can be useful when you want to preserve the value across a soft reset. Caveat: Note that on microcontrollers featuring an L1 cache, cache reinitialization may cause the runtime value of the variable to change. For devices with an L1 cache and a Memory Protection Unit (MPU), you may choose to use the Memory Protection Unit to create an uncached region of RAM and place the persistent variable into that region.
section ("section-name")
Place the variable into the named section.
For example,
unsigned int dan __attribute__ ((section (".quixote")))
Variable dan
will be placed in section .quixote
.
The -fdata-sections
command line option has no effect on variables defined with a section
attribute unless unique_section
is also specified.
space(memory-space)
The space
attribute can be used to direct the compiler to allocate a variable in a specific memory space. Valid memory spaces are prog
for program memory and data
for data memory. The data
space is the default space for non-const
variables.
The prog
and data
spaces normally correspond to the rom
, ram
memory regions, respectively, as specified in the default device-specific linker scripts.
space(data)
, but it does not generate an entry for space(prog)
, since the variable is located in non-volatile memory. Typically, this means that space(data)
applies to variables that will be initialized at runtime startup; while space(prog)
apply to variables that will be programmed by an in-circuit programmer or a bootloader. For example:const unsigned int __attribute__((space(prog))) jack = 10;
signed int __attribute__((space(data))) oz = 5;
tcm
The tcm
attribute can be applied to data items, where it directs the linker
to place the item in the appropriate tightly-coupled memory (TCM) section, that being
dtcm
, or tcm
on those processors where the code and data
memory spaces are combined. If no such section is specified in the linker script, this
attribute is ignored and a warning is printed. TCM can be used to provide faster and more
predictable execution. See 10 Chip-Level Security and Arm® TrustZone®
Technology for more details on TCM. This attribute will generally not be supported by
other distributions of gcc.
unique_section
Place the variable in a uniquely named section, just as if -fdata-sections
had been specified. If the variable also has a section
attribute, use that section name as the prefix for generating the unique section name.
For example,
int tin __attribute__ ((section (".ofcatfood"), unique_section)
Variable tin
will be placed in section .ofcatfood
.
unused
Indicate to the compiler that the variable may not be used. The compiler will not issue a warning for this variable if it is not used.
used
Indicate to the compiler that the object is always used and storage must be allocated for the object, even if the compiler cannot see a reference to it. For example, if inline assembly is the only reference to an object.
weak
The weak
attribute causes the declaration to be emitted as a weak symbol. A weak symbol indicates that if a global version of the same symbol is available, that version should be used instead.
When weak
is applied to a reference to an external symbol, the symbol is not required for linking. For example:
extern int __attribute__((weak)) s;
int foo() {
if (&s) return s;
return 0; /* possibly some other value */
}
In the above program, if s
is not defined by some other module, the program will still link but s
will not be given an address. The conditional verifies that s
has been defined (and returns its value if it has). Otherwise '0
' is returned. There are many uses for this feature, mostly to provide generic code that can link with an optional library.