Hi,
please can someone try this little code snippet with the C51 compiler and tell me why I am getting a "Linker Warning L13: Recursive Call to Segment Foo1, Caller: Foo2"
void foo1(void); void foo2(void); void (*function_pointer)(void) = &foo1; void set_function(void(*p_function_pointer)(void)) { function_pointer = p_function_pointer; } void execute(void) { (*function_pointer)(); } void foo1(void) { set_function(&foo2); } void foo2(void) { bit Linker_Warning_Comes_With_Definition_Of_This_Bit; set_function(&foo1); } void main() { execute(); }
Or a little bit shorter:
void foo1(void); void foo2(void); void (*function_pointer)(void) = &foo1; void foo1(void) { function_pointer = &foo2; } void foo2(void) { //linker warning comes with definition of this variable //Without this variable or if the variable is static, no warning occurs char var; function_pointer =&foo1; } void main() { (*function_pointer)(); }
Output is:
Build target 'Target 1' compiling main.c... MAIN.C(17): warning C280: 'var': unreferenced local variable linking... *** WARNING L13: RECURSIVE CALL TO SEGMENT SEGMENT: ?PR?FOO1?MAIN CALLER: ?PR?FOO2?MAIN Program Size: data=13.0 xdata=0 code=182 "function_pointer_test" - 0 Error(s), 2 Warning(s).
The linker isn't executing the code. But in this case, it sees that the two functions contains references to each other. That you don't actually make the call is probably outside the scope of the linker to notice.
Anyway - the 8051 is not an architecture where you should design your programs around function pointers. The compiler/linker needs to do huge amounts of tricks to try to make best use of the HLL-unfriendly processor. Function pointers are doing their best to make it hard for the compiler/linker to know who calls what, to evaluate the full call trees.
I wrote an article about overlay a while ago.
Why not check out my blog at http://www.kneeltronicals.com ?
Thanks. This means there is no mistake on my part and I can ignore this warning? I thought a function pointer it is a good solution for a LCD menu, to switch to other menus, but I could also do this with a switch statement.
I thought a function pointer it is a good solution for a LCD menu, to switch to other menus
In general, that can be a very good solution but the 8051 does not have sufficiently suitable resources to do it so well.
After a consultant? I'm your man.
Most programs makes implements data-drive menu systems, and then have each menu have an ID that gets processed. It will then let the compiler/linker know that the different menu action functions will never be called recursively.
Thank you! Then I better avoid using function pointers.
Not necessarily - just make sure that you fully understand the issues with function pointers in Keil C51 and follow the advice:
http://www.keil.com/appnotes/docs/apnt_129.asp
http://www.keil.com/support/docs/2429.htm
http://www.keil.com/support/docs/210.htm
http://www.keil.com/support/docs/2379.htm
http://www.keil.com/support/docs/1887.htm
http://www.keil.com/support/docs/1026.htm
http://www.keil.com/support/docs/996.htm