I have following codes: void fun1(unsigned char *msg); void fun2() { fun1("ssss"); } void fun3() { } code void (*func_array[])()={fun2, fun3}; void fun1( unsigned char *msg) { (*func_array[1])(); } void main() { (*fun_array[0])(); } when compiling, i got the following message *** WARNING L13: RECURSIVE CALL TO SEGMENT SEGMENT: ?CO?HELLO Could you please tell me how to solve it? Thanks a lot!
http://www.keil.com/forum/tips.asp http://www.keil.com/appnotes/docs/apnt_129.asp http://www.keil.com/support/docs/210.htm http://www.keil.com/support/docs/806.htm
I think my situation is a little different from what those APP discuss.
PROGRAM RECURSIONS REMOVED FROM CALL TREE ========================================= +--> ?CO?HELLO | | ?PR?FUN2?HELLO <--+ ?PR?_FUN1?HELLO
Why don't you cut and paste the code that you are actually using?
because the original code is too complex! I am afraid that you guys may lose interests! I use two function pointer tables, so recursive calls problem comes out! Can you please tell me where can I find examples of how to use multi-function pointer tables and one table depends on the other table. Thanks a lot!
Did you look at http://www.keil.com/appnotes/docs/apnt_129.asp? Jon
use two function pointer tables That is PC C, not '51 C Mend your ways and adapt your coding style to the processor you are using. Practices like that can kill a '51 better than a voltage surge. Erik
If the techniques in the aforementioned App. Note #129 do not suit you, an alternative is to codify the function pointer array at the cost of an additional pushed return address.
void func_array(unsigned char idx) { switch (idx) { case 0: fun2(); break; case 1: fun3(); break; case 2: fun4(); break; case 3: fun5(); break; case 4: fun6(); break; /* ... */ } }
"...codify the function pointer array..." That is, if your function pointer arrays are constant (i.e., are not modified during runtime).
If you dynamically update the function pointer table, then there is no way for the static call tree analysis to help you. So, you'll be in for a lot of work with the OVERLAY directive, or else a lot of code bloat from the reentrant declaration. Unless you're doing extremely dynamic things like creating code to execute on the fly, you probably know the range of possible results, and can use an index into a table of fixed pointers. "Call func 3" works about as well as "Call func *p" in most cases. It's perhaps worth noting that a switch statement such as the one Dan posted generally compiles into a jump table anyway. You don't have to explicitly code a function pointer table to get a table of function pointers. I often get a recursive call to segment warning from code with structure like this:
char const code * code StringTable[] = { "Name1", "Name2" } void f1 (int i) { printf (StringTable[i]); } void f2 (int i) { PerformWonders(i); } const code FuncTableEntry FuncTable[2] = { f1, f2 }; void Dispatcher (void) { FuncTable(i); }
Thank you all guys! I cut and paste part of my codes and solution here. HOPE that you still keep one eye on that, and any suggestion is very welcome! The situation is the codes are not only intended for C51, but also for other processor! I prefer a general structure for all platforms, and It seem that using two function pointer tables is a good way. Firstly, I have the following data structure for function pointer tables.
……. typedef Bool (*FnDrawing)(Void); typedef Void (*FnDrawed)(Void); typedef Bool (*FnProcessingKey)(Void); typedef Void (*FnProcessedKey)(Void); ………. typedef struct tagStruct { ………………….. FnProcessingKey fnProcessingKey; FnProcessedKey fnProcessedKey; FnDrawing fnDrawing; FnDrawed fnDrawed; ………………… } nuStruct; typedef nuStruct * RPnuStruct;
Code nuStruct MainStruct = { ………….. MainProcessingKey, MainProcessedKey, MainDrawing, MainDrawed, ……………………. }; Code nuStruct TnuStruct = { ………….., TProcessingKey, TProcessedKey, TDrawing, TDrawed, ……………… }; ……
Code nuStruct * Code c_nuTable[] = { ………………. &MainnuStruct, …………… &TnuStruct, ………….. };
It is a very trial task which costs me half a day, That is the cost of programming a '51 as if it were a PC. Erik
Dan: "... codify the function pointer array at the cost of an additional pushed return address." Drew: "It's perhaps worth noting that a switch statement such as the one Dan posted generally compiles into a jump table anyway." And when it compiles into a jump table, it does not cost an additional pushed return address.