Keil Logo

Function Pointers

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 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 functions.
  • 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.

Note

  • 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.

  1. 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 program crash.
  2. 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 properly managed.

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

  Arm logo
Important information

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies.

Change Settings

Privacy Policy Update

Arm’s Privacy Policy has been updated. By continuing to use our site, you consent to Arm’s Privacy Policy. Please review our Privacy Policy to learn more about our collection, use and transfers
of your data.