16.2.1 Function Attributes
The compiler keyword __attribute__
allows you to specify special attributes of functions. 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., __noreturn__
instead of noreturn
). This allows you to use them in header files without being concerned about a possible macro of the same name.
__attribute__ ((address(0x100), keep))
The attribute specifier can be placed either before or after the function's return type.
extern
in file B without the same attribute, then a link error might result.address(addr)
The address attribute specifies an absolute physical address at which the attributed routine will be placed in memory. It can be used with C and C++ functions.
The compiler performs no error checking on the address value, so the application must ensure the value is valid for the target device. The section containing the function will be located at the specified address regardless of the memory-regions specified in the linker script or the actual memory ranges on the target device. The application code must ensure that the address is valid for the target device.
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
sections. 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.
alias ("symbol")
void foo (void) { /* stuff */ }
__attribute__ ((alias("foo"))) void bar (void);
In the above example, the symbol bar
is considered to be an alias for the symbol foo
.
always_inline
Instructs the compiler to always inline a function declared as inline
, even if no optimization level was specified.
const
If the result of a pure function is determined exclusively from its parameters (i.e., does not depend on the values of any global variables), it may be declared with the const
attribute, allowing for even more aggressive optimization. Note that a function which de-references a pointer argument cannot be declared const
if it depends on the referenced value, as the referenced storage is not considered a parameter of the function.
deprecated
deprecated (msg)
When a function specified as deprecated
is used, the compiler will generate a warning. The optional msg
argument, which must be a string, will be printed in the warning if present. The deprecated
attribute may also be used for variables and types.
externally_visible
This attribute when used with a function ensures the function remains visible outside the current compilation unit. This might prevent certain optimizations from being performed on the function.
format (type, format_index, first_to_check)
The format
attribute indicates that the function takes a printf
, scanf
, strftime
, or strfmon
style format string at position index
in the argument list, and instructs the compiler to type-check the arguments starting at first_to_check
against the conversion specifiers in the format string, just as it does for the standard library functions.
The type
parameter is one of printf
, scanf
, strftime
or strfmon
(optionally with surrounding double underscores, e.g., __printf__
) and determines how the format string will be interpreted.
The format_index
parameter specifies the position of the format string in the function's parameters. Function parameters are numbered from the left, starting from index 1.
The first_to_check
parameter specifies the position of the first parameter to check against the format string. All parameters following the parameter indicated by first_to_check
will be checked. If first_to_check
is zero, type checking is not performed, and the compiler only checks the format string for consistency.
format_arg(index)
The format_arg
attribute specifies that a function manipulates a printf
style format string and that the compiler should check the format string for consistency. The index
parameter gives the position of the format string in the parameter list of the function, numbered from the left beginning at index 1.
interrupt
interrupt(type)
Functionally equivalent to the isr
attribute.
isr
isr(type)
Instructs the compiler to generate prologue and epilogue code for the function
as an interrupt handler function, as described in 17 Interrupts. For Cortex-A
devices, the type
argument specifies the type of the
interrupt, which may be one of the identifiers irq
,
fiq
, abort
, undef
or
swi
, in lowercase or uppercase. Any argument specifed is ignore
when building for Cortex-M devices.
keep
The keep
attribute prevents the linker from removing an unused function when --gc-sections
is in effect.
long_call
Always call the function with an indirect call instruction.
malloc
The malloc
attribute asserts that any non-null pointer return value from the function will not be aliased to any other pointer which is live at the point of return from the function. This allows the compiler to perform more aggressive optimizations.
naked
Indicates that the compiler should generate no prologue or epilogue code for the function.
noinline
A function declared with the noinline
attribute will never be considered for inlining, regardless of optimization level.
nonnull(index, ...)
Indicate to the compiler that one or more pointer arguments to the function must be non-null. When the -Wnonnull
option is in effect, the compiler will issue a warning diagnostic if it can determine that the function is called with a null pointer supplied for any nonnull
argument. The index
argument(s) indicate the position of the pointer arguments required to be non-null in the parameter list of the function, numbered from the left starting at index 1. If no arguments are provided, all pointer arguments of the function will be marked as non-null.
nopa
Indicate to the compiler that the assembly code generated for this function should not be considered when performing procedural abstraction.
noreturn
Indicate to the compiler that the function will never return control to its caller. In some situations, this can allow the compiler to generate more efficient code in the calling function, since optimizations can be performed without regard to behavior if the function ever did return. Functions declared with noreturn
should always have a void return type.
optimize(optimization)
optimize
attribute allows a function to be built with optimizations that differ to what has been specified on the command line and which will be applied to the rest of the program. The optimization
argument can either be a number or a string. String arguments represent the command-line option used to control an optimization, so for example, to enable peephole optimizations (-fpeephole
), use optimize("peephole")
. The -f
option prefix does not need to be specified with the argument. If you want to specify more than one optimization, separate the arguments with commas but with no space characters. Arguments that begin with O
are assumed to be an optimization level option, for example optimize("O1,unroll-loops")
turns on level 1 optimizations and the unroll-loops optimizations (controlled by the -funroll-loops
command-line option). A numerical argument is also assumed to be an optimization level, for example optimize(3)
turns on level 3 optimizations and is equivalent to the full usage of the attribute in the following example. int __attribute__((optimize("O3"))) pandora (void) {
if (maya > axton)
return 1;
return 0;
}
This feature can be used, for instance, to have frequently executed functions compiled with more aggressive optimization options that produce faster and larger code, while other functions can be called with less aggressive options. Typically, however, it is not used for production builds.pure
Indicates to the compiler that the function is pure, allowing for more aggressive optimizations in the presence of calls to the function. A pure
function has no side effects other than its return value, and the return value is dependent only on parameters and/or (non-volatile) global variables.
ramfunc
The ramfunc
attribute locates the attributed routine in RAM rather than in Flash
memory on devices that normally execute code from Flash. This attribute can be used for
both C functions and C++ class methods. The compiler's default runtime startup code uses
the data-initialization template to copy the code associated with functions using this
attribute from Flash to RAM at program startup.
__attribute__((ramfunc))
unsigned int myramfunct(void)
{ /* code */ }
The <sys/attribs.h>
header file
provides a __ramfunc__
macro that is useful for this purpose. For
example:#include <sys/attribs.h>
__ramfunc__ unsigned int myramfunct(void)
{ /* code */ }
class printmyname {
// Access specifier
public:
// Data Members
string myname;
int dummy ;
// Member Functions()
printmyname (){
myname = "microchip";
}
void __attribute__((ramfunc, long_call)) set_name(string newname){
myname = newname;
dummy = 9;
}
void printname() { cout << "name is:" << myname; }
};
BL
has a limited range (32MB for ARM instructions, 16MB for Thumb2 and 4MB for Thumb). As a result, RAM might not be within range of calls made from code in Flash. To allow such calls, additionally use the long_call
attribute with the definition of the function located in RAM when it must be called from functions in Flash. For example:__attribute__((ramfunc, long_call))
unsigned int myramfunct(void)
{ /* code */ }
The <sys/attribs.h>
header file provides a __longramfunc__
macro that will specify both the ramfunc
and long_call
attributes. For example:#include <sys/attribs.h>
__longramfunc__ unsigned int myramfunct(void)
{ /* code */ }
long_call
attribute.__attribute__ ((long_call))
unsigned int myflashfunct(void)
{ /* code */ }
__attribute__((ramfunc))
unsigned int myramfunct(void)
{
return myflashfunct();
}
Having functions located in RAM rather than Flash can increase code size as well as startup time, as the attributed functions must be copied from Flash to RAM at startup. It may also have an impact on runtime performance, depending on your target device. Verify that your application meets your startup timing constraints. Also verify that the increased runtime performance meets your application's timing requirements and that your application does not have hidden dependencies on timing that is negatively impacted by this design selection.
section("name")
Place the function into the given named section. For example:
void __attribute__ ((section (".wilma"))) baz () {return;}
In the above example, function baz
will be placed in section .wilma
. The -ffunction-sections
command line option has no effect on functions declared with the section
attribute.
short_call
Always call the function using an absolute call instruction, even when the -mlong-calls
command line option is specified.
space(id)
Place the function in the memory space identified by the id
argument. The id
argument may be prog
, which places the function in the program space (i.e., ROM), or data
, which places the function in a data section (i.e., RAM). Unlike the section
attribute, the actual section is not explicitly specified.
stack_protect
This attribute adds stack protection code to the function if one of the following options is set: -fstack-protector
, -fstack-protector-strong
, or -fstack-protector-explicit
.
Optimizations can affect stack protection:
- Function inlining can affect whether a function is protected.
- Removal of an unused variable can prevent a function from being protected.
tcm
Attempt to place the function in tightly-coupled memory (TCM), providing highly consistent access times. The actual section will be determined by the compiler, possibly based on other attributes such as space
. For example:
void __attribute__((tcm)) foo (void) {return;}
In the above example, the compiler will attempt to place foo
in
the itcm
memory section, or the tcm
section on those
processors where the code and data memory spaces are combined. Note that the amount of
TCM available in program or data memory on the target device may vary, so the compiler
cannot ensure all functions with the tcm
attribute can be placed in
TCM.
Also see 7.5 Tightly-Coupled Memories.
unique_section
Place the function in a uniquely named section, as if -ffunction-sections
were in effect. If the function also has a section
attribute, the given section name will be used as a prefix for the generated unique section name. For example:
void __attribute__ ((section (".fred"), unique_section) foo (void) {return;}
In the above example, function foo
will be placed in section .fred.foo
.
unsupported
Indicate to the compiler that the function is not supported, similar to the deprecated
attribute. A warning will be issued if the function is called.
unused
Indicate to the compiler that the function may not be used. The compiler will not issue a warning for this function if it is not used.
used
Indicate to the compiler that the function is always used and code must be generated for the function even if the compiler cannot determine that the function is called, e.g., if a status function is only called from an inline assembly statement.
warn_unused_result
A warning will be issued if the return value of the indicated function is unused by a caller.
weak
A weak symbol indicates that if another version of the same symbol is available, that version should be used instead. For example, this is useful when a library function is implemented such that it can be overridden by a user written function.