16.2.1 Function Attributes
access(access-mode, ref-index[,
size-index])
The access attribute provides additional information about how a
function accesses memory. It can assist in diagnosing potential bugs related to memory
access via compiler warnings and help the compiler perform better optimizations.
The ref-index argument is the index (starting from the
left with index 1) of the function pointer argument that points to the target object
being accessed. A function pointer argument can be referenced by at most one distinct
access attribute.
access_mode argument specifies the type of memory
access made by the pointer referenced by the ref-index
and can be one of the following:read_only- The pointer only reads from the target object. Unless the indexed size
argument is zero, the target object must be initialized. This check is more
robust than just using the
constqualifier with the target as it cannot be cast away. write_only- The pointer (which cannot be to a
const-qualified type) only writes to the target object. The object referenced by the pointer need not be initialized. read_write- The pointer (which cannot be to a
const-qualified type) both reads from and writes to the target object. Unless the indexed size argument is zero, the target object must be initialized. none- The pointer does not access the target object at all. Unless the pointer is
NULL, the target object must exist and have at least the size held by the size-index argument. If the size-index argument is omitted for a pointer ofvoid *type, the actual pointer argument is ignored. The referenced object need not be initialized. The mode is intended to be used as a means to help validate the expected object size, for example in functions that call__builtin_object_size.
The optional size-index argument is the index of the
function argument that specifies the number of elements of the pointer type referenced
by ref-index, or the number of bytes when the pointer
type is void *. When this argument is not specified, the pointer
argument must be either NULL or point to a space that is suitably
aligned and sized for at least one object of the referenced type (this implies that a
past-the-end pointer is not a valid argument). The actual size of the access may be less
but it must not be more.
access attribute to declare
that the pointer argument to puts() will only read its target of
unspecified size. The attribute is used again to indicate that the second argument to
memcpy() only reads its target and that this target has a size
indicated by the value of the third function
argument.__attribute__ ((access (read_only, 1))) int puts(const char *);
__attribute__ ((access (read_only, 2, 3))) void * memcpy(void *, const void *, size_t);address(addr)
__attribute__((address(0x460000))) void bar (void);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.
Sections used to hold functions placed at an absolute address will use a name
.address.N.decl, where
N is the address and
decl is the name of the declaration.
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
inline, even if no optimization level was specified, for
example:void __attribute__ ((always_inline)) foo (void);const
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. For
example:int __attribute((const)) rv(int a);deprecated
deprecated (msg)
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, for
example:void __attribute__ ((deprecated ("The bar function is no longer used"))) bar (void);externally_visible
void __attribute__((externally_visible)) foo (void);format (type, format_index, first_to_check)
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, for
example:extern int __attribute__ ((format (printf, 2, 3))) my_printf (void * my_object, const char *my_format, ...);
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)
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. For
example:extern char * __attribute__ ((format_arg (2))) my_foo (char *my_str, const char *my_format);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 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
keep attribute prevents the linker from removing an unused
function when --gc-sections is in effect, for
example:void __attribute__((keep)) foo(void);long_call
void __attribute__((long_call)) foo(void);malloc
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, for
example:void __attribute__ ((malloc)) *custom_malloc (int size_t); naked
void __attribute__ ((naked)) foo(void);noinline
noinline attribute will never be
considered for inlining, regardless of optimization level, for
example:void __attribute__ ((noinline)) foo(void);nonnull(index, ...)
-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. For
example:void * __attribute__((nonnull)) my_memset (void * ptr, int x, size_t len);nopa
void __attribute__((nopa)) setMode (char * msg, unsigned t_sec);noreturn
noreturn
should always have a void return type. For
example:void __attribute__ ((noreturn)) myExit(void);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
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,
for
example:void __attribute__ ((pure)) foo(void);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
-mlong-calls command line option is specified, for
example:void __attribute__ ((short_call)) foo(void);space(id)
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, for
example:void __attribute__ ((space(prog))) foo(void);[no_]stack_protector
stack_protector 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. For
example:void __attribute__ ((stack_protector)) foo(void);- Function inlining can affect whether a function is protected.
- Removal of an unused variable can prevent a function from being protected.
The no_stack_protector attribute can alternatively be used to disable
protection for the specified function, even when one of the stack protection options has
been issued.
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 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
deprecated attribute. A warning will be issued if the function is
called. For
example:void __attribute__ ((unsupported)) legacyRead(void);unused
void __attribute__ ((unused)) opt_setting(void);used
void __attribute__ ((used)) foo(void);warn_unused_result
void __attribute__ ((warn_unused_result)) foo(void);weak
void __attribute__ ((weak)) foo(void);