5.4.2.2 Automatic Storage Duration Objects
Objects with automatic storage duration, such as auto, parameter objects, and temporary variables, are typically allocated space on a stack implemented by the compiler.
MPLAB XC8 has two stack implementations: a compiled stack and a software stack (described in 5.7.2 Data Stacks). Each C function is compiled to use exactly one of these stacks for its automatic storage duration objects and the table below summarizes how the choice of stack affects a function’s reentrancy.
Data Stack Used | Function Model | Supported Device Families |
---|---|---|
Compiled stack | Non-reentrant | All devices |
Software stack | Reentrant | Enhanced Mid-range and PIC18 devices |
When compiling for those devices that do not support the reentrant function model, all functions are encoded to use the compiled stack, which are non-reentrant functions.
For the Enhanced Mid-range and PIC18 devices, by default the compiler will
use the non-reentrant model for all functions. The -mstack
option (see
4.6.1.23 Stack Option) can be used to
change the compiler’s default behavior when assigning function models. Select the
software
argument with this option so that the compiler will always
choose the reentrant model (software stack) for each function. Set this option to
hybrid
to allow the compiler to decide how each function should be
encoded. If the function is not reentrantly called, then it will be encoded to use the
non-reentrant model and the compiled stack. If the function appears in more than one call
graph (i.e., it is called from main-line and interrupt code), or it appears in a loop in a
call graph (i.e., it is called recursively), then the compiler will use the reentrant
model. The hybrid mode allows the program to use recursion but still take advantage of the
more efficient compiled stack.
Alternatively you can change the function model for individual functions
by using function specifiers when you define the function. Use either the
__compiled
or __nonreentrant
specifier (identical
meanings) to indicate that the specified function must use the compiled stack, without
affecting any other function. Alternatively, use either the __software
or
__reentrant
specifier to indicate a function must be encoded to use the
software stack.
The function specifiers have precedence over the -mstack
option setting. If, for example, the option -mstack=compiled
has been
used, but one function uses the __software
(or
__reentrant
) specifier, then the specified function will use the software stack
and all the remaining functions will use the compiled stack. These functions specifiers
also override any choice made by the compiler in hybrid mode.
If the -mstack=compiled
option has been issued or a
function has been specified as __compiled
(or
__nonreentrant
) and that function appears in more than one call graph
in the program, then a function duplication feature automatically comes into effect (see
5.9.7 Function Duplication). Duplicating
a non-reentrant function allows it to be called from multiple call graphs, but cannot allow
the function to be called recursively.
The auto objects defined in a function will not necessarily be allocated memory in the order declared, in contrast to parameters which are always allocated memory based on their lexical order. In fact, auto objects for one function can be allocated in many RAM banks.
The standard const
qualifier can be used with auto
objects and forces them to be read-only. These objects, however, might not be stored on the
stack. See 5.1.2.4 Const Auto Objects for how
the compiler allocates such objects.