This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Linker warning L13 with function pointers

I want to call a number of functions with function pointers. I have studied a number of posts and App. notes, including APNT 129 and I am still getting a linker error. On page 7 of APNT 129 is says:-
The following is a function pointer table definition that C51 and BL51 can handle automatically:
code long (code *fp_tab []) (void) =
{ func1, func2, func3 };
Note that the only difference is storing the table in CODE space.

and later:-
As long as the function pointer table is located in a separate source file, C51 and BL51 make all
the correct links in the call tree for you.

I assume the .h file is OK for "a separate source file"

Here is my code:-
in the myprog.h file:-

extern uchar set_day(uchar xpos, uchar ypos, uchar action);
extern uchar set_hours(uchar xpos, uchar ypos, uchar action);
extern uchar set_mins(uchar xpos, uchar ypos, uchar action);

// Function pointer table

code uchar(code *set_table[])(uchar, uchar, uchar) = {set_day, set_hours, set_mins};


in the myprog.c file:-

#include "myprog.h"

/* Declarations*/
........
........

main(){

.....
.....
// function called with:-
(*set_table[0])(an_xval, a_yval, an_action);
.....
.....
.....
}

// Functions:- (after main() in myprog.c)

uchar set_day(uchar xpos, uchar ypos, uchar action){
...
...
}

set_hours(uchar xpos, uchar ypos, uchar action){
...
...
}

set_mins(uchar xpos, uchar ypos, uchar action){
...
...
}


When I link this, I get three L13 warnings.
The M51 file reports:-

...
...
PROGRAM RECURSIONS REMOVED FROM CALL TREE
=========================================
+--> ?CO?RGE_MAIN_04
<--+ ?PR?_SET_DAY?RGE_MAIN_04


+--> ?CO?RGE_MAIN_04
<--+ ?PR?_SET_HOURS?RGE_MAIN_04


+--> ?CO?RGE_MAIN_04
<--+ ?PR?_SET_MINS?RGE_MAIN_04
...
...
*** WARNING L13: RECURSIVE CALL TO SEGMENT
    SEGMENT: ?CO?RGE_MAIN_04
    CALLER:  ?PR?_SET_DAY?RGE_MAIN_04

*** WARNING L13: RECURSIVE CALL TO SEGMENT
    SEGMENT: ?CO?RGE_MAIN_04
    CALLER:  ?PR?_SET_HOURS?RGE_MAIN_04

*** WARNING L13: RECURSIVE CALL TO SEGMENT
    SEGMENT: ?CO?RGE_MAIN_04
    CALLER:  ?PR?_SET_MINS?RGE_MAIN_04

I would rather not have these warnings but is it safe to ignore them, bearing in mind the code seems to work when I download it. (I have only called the first pointer so far.)

  • Hello Simon,

    I had a bunch of these warnings in a program some years ago. It was the same cause: calling functions via funtion pointers.
    As I was sure that there was no recursive behaviour at all, I chose to ignore these warnings.
    That program had recently been extended a little, so I stumbled across the warning messages again (that's why I remembered their existence in such an "old" program).

    There were never any problems with the application (some 10000 units sold...).

    Just my 2 cents,
    Carsten

  • "I want to call a number of functions with function pointers"

    You may want to, but do you really need to?
    As you must have gathered by now, there are good reasons to avoid function pointers in C51 unless you really need them.

    Anyhow, assuming that you have considered the alternatives and decided that it's worth the effort...

    "I assume the .h file is OK for 'a separate source file'"

    Absolutely not!

    The reason for the separate source file is so that the pointer definitions are all in a module of their own.

    Your header file does not contain definitions - only extern declarations

    c-faq.com/.../decldef.html

    It's the definitions that actually create the table in memory...

  • Note that the message says "recursive call to segment". This is not a warning about a recursive function. It means that the entire code segment -- the .c file -- refers to itself. There's a function that calls other functions from the table of pointers. That table is part of the same segment. Those functions likely also call other functions or constant data in that segment. Hence, the recursion.

    If you move the function pointer table to a separate .c file as recommended by the app note, the warnings should go away, because then the functions and table will be in separate segments.

  • Andy and Drew,

    Thanks for your help. Yes, it works when I move the pointer to a separate .c file and not a .h file. I had a bit of fun working out how to declare it, however. One must initialise and assign the pointer in the separate file but then you have to tell the compiler where the function names are to which the thing points without getting involved in more recursions.

    The way I did this was to put the function prototypes in the header file and include this file in both the main and function pointer source files:-

    // func_ptr_tab.c
    #include myprog.h
    // Function pointer table
    
    code uchar(code *set_table[])(uchar, uchar, uchar) = {set_day, set_hours, set_mins};
    .....
    


    Then in myprog.h:-

    .....
    uchar set_day(uchar xpos, uchar ypos, uchar action);
    uchar set_hours(uchar xpos, uchar ypos, uchar action);
    uchar set_mins(uchar xpos, uchar ypos, uchar action);
    .....
    


    Finally, myprog.c is the same as before.

    Cheers,

    Simon

  • "The way I did this was to put the function prototypes in the header file and include this file in both the main and function pointer source files"

    Yes, that is the normal way to "publish" symbols to be accessed by external modules - it's not specific to function pointers or Keil.