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 C251 Compiler passes up to three (3) arguments in
registers. Do not assume that just any three arguments fit into
registers. Refer to Passing in
Registers in the C251 User's Guide for more information.
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
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 uses 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 have
the effect of corrupting a function pointer, which is likely to
cause a program crash.
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)) ...