Function pointers (and indirectly-called functions) present some
special issues that must be taken into consideration when creating
functions that are called indirectly.
Function Parameters may be passed only in registers to
indirectly-called functions. The typical parameter passing scheme
which overlays function parameters and variables may not be used
because the compiler does not necessarily know the name of the
function called through the pointer.
By default, the Cx51 Compiler passes up to three (3) arguments in
registers. Do not assume that just any three arguments fit into
registers. Refer to Parameters
and Registers in the C51/CX51 User's Guide for more
If you require more parameters than will fit into registers, you
must merge them into a structure and pass a pointer to the
structure. If that is unacceptable, you may use reentrant
The Call Tree that is automatically generated by the
linker, must be adjusted using the OVERLAY directive to include proper
references to indirectly-called functions.
If you attempt to pass more than three arguments through a
pointer to a function, the compiler generates an error message.
No warning or error is generated if you neglect to adjust the
call tree when function pointers are used.
There are two very good reasons why you must adjust the call tree
if you use function pointers.
The linker uses references to build the call tree. If a
function initializes a function pointer variable or passes the
address of a function to another function, the linker interprets
this as a reference and adds a call to the function into the call
tree. Later, when the function is actually called through the
function, it will use data space that may be overlaid with a
function farther up the branch and cause data corruption. If you
pass function pointers as arguments, this could even have the
effect of corrupting a function pointer which would likely cause a
In some cases, it may seem easier to simply disable overlay
analysis or to simply remove functions called through pointers from
the call tree. However, this leads to wasted memory. If you only
remove the function from the call tree, you must keep in mind that
functions called by the indirectly-called function may overlay
their variables. This may also cause data corruption if it is not
The easiest solution for indirectly-called functions is to remove
them from the call tree. For example:
... OVERLAY (sfname-caller ~ (sfname-callee, sfname-callee)) ...
And, then add specific references from the calling functions to
the indirectly-called function. For example:
... OVERLAY (sfname-caller ! (sfname-callee, sfname-callee)) ...
Related Knowledgebase Articles