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

adding reentrant to typedef function pointers causes redefinition in code

I am porting some code to an 8051.

(header.h)

typedef int     (Writer) (int ,
                                   u_char * ,
                                   u_char ,
                                   size_t ,
                                   u_char * ,
                                   int *) reentrant;
(source.h)
Writer bob;

(source.c)
.
.
.
int     bob(int val1,
            u_char * dat1,
            u_char dat2,
            size_t val2,
            u_char * dat3,
            int *pval) reentrant
{
}

When I attempt to compiler this, I get
error C231: '_bob' : redefinition. If I go to source.h and do the following:
(source.h)
//Comment out Writer bob;
int     (bob)(int val1,
            u_char * dat1,
            u_char dat2,
            size_t val2,
            u_char * dat3,
            int *pval) reentrant;


It compiles fine. Is this a limitation of the compiler? Any shortcuts I could use so I don't have to rewrite large chunks of code

Parents
  • The problem is not really the typedef itself --- which is a function type, rather than the function pointer type your subject alludes to. The problem is how you use it.

    Writer  bob;

    is a tentative definition of a function object "bob", and you put it into a header file. That's wrong --- you don't want object definitions in headers. Make that

    extern Writer bob;

    and you'll be getting somewhere.

    If you really want Writer to be a function pointer type, you'll have to change the typedef, and you can't have bob both as the name of the pointer and the name of the function it points to, at the same time.

Reply
  • The problem is not really the typedef itself --- which is a function type, rather than the function pointer type your subject alludes to. The problem is how you use it.

    Writer  bob;

    is a tentative definition of a function object "bob", and you put it into a header file. That's wrong --- you don't want object definitions in headers. Make that

    extern Writer bob;

    and you'll be getting somewhere.

    If you really want Writer to be a function pointer type, you'll have to change the typedef, and you can't have bob both as the name of the pointer and the name of the function it points to, at the same time.

Children
  • The .h file provides a "prototype" of a function to be defined elsewhere. The redefinition warning means that when you actually define the function in the .c file, it does not match a previously seen declaration (typically in a .h file).

    While you've run into this problem with the reentrant attribute, it applies to any change in function signature. That is,

    .h:
    void MyFunction (long a);

    .c:
    void MyFunction (short a);

    would produce a redefinition warning.

    The .h file should always match the actual definition of the function, lest you confuse seperately-compiled callers.

  • The .h file provides a "prototype" of a function to be defined elsewhere.

    That what it should do, for ordinary functions. But the case at hand is different, because

    Writer bob;
    is not a correct prototype declaration: the extern keyword is missing. As is, it's a tentative definition of a function object named "bob". I.e. every .c file this header is included in will have an (empty) function called bob inside. The linker complains about that, and it's right to do so.

    The redefinition warning means that when you actually define the function in the .c file, it does not match a previously seen declaration (typically in a .h file).

    No. For that you would get a "mismatch with previous declaration" warning/error from the compiler, not a redefinition complaint from the linker.

    The .h file should always match the actual definition of the function, lest you confuse seperately-compiled callers.

    Right. And the proper way of making sure of this is to always include the module's header file into its own .c file.

  • "the proper way of making sure of this is to always include the module's header file into its own .c file."

    Yep - that's what I always say!

  • Thank you for the help. Extern did not improve anything unforunately. It appears that it is coded this way because the function is also passed within structures and other functions. In this way, we are not rewriting all of the details of the function pointer.

    This style is being used quite often in the code. I only seem to have a problem when I am forced to define the function as reentrant(too many arguments).

    For example:

    (header.h)
    
    typedef int     (Writer) (int);
    
    Writer bob;
    

    (header.c)
    
    int bob(int a){
    ...
    }
    

    Is not a problem.

    I am only having the problem when the function is too large and I have to redefine it as reentrant. Then I can not use the Writer type, but instead have to explicitly declare the function prototype and add the reentrant attribute to the prototype and function header.
    I am doing this right now, but there is a lot of code and I was hoping there was a better way.

  • "I am only having the problem when the function is too large and I have to redefine it as reentrant."

    Why does the Size of the function affect the need for the reentrant attribute?