Microchip Technology SW006021-1N Benutzerhandbuch
MPLAB
®
XC8 C Compiler User’s Guide
DS52053B-page 156
2012 Microchip Technology Inc.
5.4.5.3
FUNCTION POINTERS
The MPLAB XC8 compiler fully supports pointers to functions, which allows functions
to be called indirectly. These are often used to call one of several function addresses
stored in a user-defined C array, which acts like a lookup table.
to be called indirectly. These are often used to call one of several function addresses
stored in a user-defined C array, which acts like a lookup table.
For baseline and mid-range devices, function pointers are always one byte in size and
hold an offset into a jump table that is output by the compiler. This jump table contains
jumps to the destination functions.
hold an offset into a jump table that is output by the compiler. This jump table contains
jumps to the destination functions.
For PIC18 devices, function pointers are either 16 or 24 bits wide. The pointer size is
purely based on the amount of program memory available on the target device.
purely based on the amount of program memory available on the target device.
As with data pointers, the target assigned to function pointers is tracked. This is an eas-
ier process to undertake compared to that associated with data pointers as all function
instructions must reside in program memory. The pointer reference graph (described in
Section 6.6.5 “Pointer Reference Graph”) will show function pointers, in addition to
data pointers, as well as all their targets. The targets will be names of functions that
could possibly be called via the pointer.
ier process to undertake compared to that associated with data pointers as all function
instructions must reside in program memory. The pointer reference graph (described in
Section 6.6.5 “Pointer Reference Graph”) will show function pointers, in addition to
data pointers, as well as all their targets. The targets will be names of functions that
could possibly be called via the pointer.
One notable runtime feature for baseline and mid-range devices is that a function
pointer which contains NULL (the value 0) and is used to call a function indirectly will
cause the code to become stuck in a loop which branches to itself. This endless loop
can be used to detect this erroneous situation. Typically calling a function via a NULL
function would result in the code crashing or some other unexpected behavior. The
label to which the endless loop will jump is called fpbase.
pointer which contains NULL (the value 0) and is used to call a function indirectly will
cause the code to become stuck in a loop which branches to itself. This endless loop
can be used to detect this erroneous situation. Typically calling a function via a NULL
function would result in the code crashing or some other unexpected behavior. The
label to which the endless loop will jump is called fpbase.
5.4.5.4
SPECIAL POINTER TARGETS
Pointers and integers are not interchangeable. Assigning an integer constant to a
pointer will generate a warning to this effect. For example:
pointer will generate a warning to this effect. For example:
const char * cp = 0x123; // the compiler will flag this as bad code
There is no information in the integer constant, 0x123, relating to the type, size or mem-
ory location of the destination. There is a very good chance of code failure if pointers
are assigned integer addresses and dereferenced, particularly for PIC devices that
have more than one memory space. Is 0x123 an address in data memory or program
memory? How big is the object found at address 0x123?
ory location of the destination. There is a very good chance of code failure if pointers
are assigned integer addresses and dereferenced, particularly for PIC devices that
have more than one memory space. Is 0x123 an address in data memory or program
memory? How big is the object found at address 0x123?
Always take the address of a C object when assigning an address to a pointer. If there
is no C object defined at the destination address, then define or declare an object at
this address which can be used for this purpose. Make sure the size of the object
matches the range of the memory locations that are to be accessed by the pointer.
is no C object defined at the destination address, then define or declare an object at
this address which can be used for this purpose. Make sure the size of the object
matches the range of the memory locations that are to be accessed by the pointer.
For example, a checksum for 1000 memory locations starting at address 0x900 in pro-
gram memory is to be generated. A pointer is used to read this data. You may be
tempted to write code such as:
gram memory is to be generated. A pointer is used to read this data. You may be
tempted to write code such as:
const char * cp;
cp = 0x900; // what resides at 0x900???
and increment the pointer over the data.
However, a much better solution is this:
const char * cp;
const char inputData[1000] @ 0x900;
cp = &inputData;
// cp is incremented over inputData and used to read values there
In this case, the compiler can determine the size of the target and the memory space.
The array size and type indicates the size of the pointer target, the const qualifier on
the object (not the pointer) indicates the target is located in program memory space.
The array size and type indicates the size of the pointer target, the const qualifier on
the object (not the pointer) indicates the target is located in program memory space.