functions that return pointer to function

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • msolem@linuxmail.org

    #1

    functions that return pointer to function

    I have some code where there are a set of functions that return
    pointers to each other. I'm having a bit of a hard time figuring out
    the correct type to use to do that.

    The code below works but I'm defining the functions as void*, and then
    casting when I use them. This code is going into a general purpose
    framework, and it would be much nicer if the user didn't need to do
    any casting.

    Can someone tell me how to set up those typedefs so that the casting
    done in main is not required?

    Thanks,
    Mike

    =============== =============== ===
    #include <stdio.h>

    typedef void* p_t;
    typedef void (*pf_t)(void);
    typedef pf_t (*ppf_t)(void);

    p_t f1(void);
    p_t f2(void);

    p_t f1(void)
    {
    printf("func1\n ");
    return f2;
    }
    p_t f2(void)
    {
    printf("func2\n ");
    return f1;
    }

    int main (void)
    {
    ppf_t var;

    var = (ppf_t)f1;
    var = (ppf_t)var();
    var = (ppf_t)var();
    var = (ppf_t)var();

    return 0;
    }
    =============== =============== ===

    The output is:
    func1
    func2
    func1

  • Michael Mair

    #2
    Re: functions that return pointer to function

    msolem@linuxmai l.org schrieb:[color=blue]
    > I have some code where there are a set of functions that return
    > pointers to each other. I'm having a bit of a hard time figuring out
    > the correct type to use to do that.[/color]

    There is none. At least not in portable C.
    For objects, you have void * as the pointer type every object pointer
    can be converted to or from.
    For functions, there is not "generic function pointer type". Using
    void * is not guaranteed to work -- there is no implicit conversion
    specified, so void * may not be able to represent function pointers
    (e.g. if program and data reside in different memory areas).
    [color=blue]
    > The code below works but I'm defining the functions as void*, and then
    > casting when I use them. This code is going into a general purpose
    > framework, and it would be much nicer if the user didn't need to do
    > any casting.[/color]

    Well, having to cast outside of the argument lists of variable
    argument functions or functions without prototypes usually
    indicates that you are doing something wrong.
    [color=blue]
    > Can someone tell me how to set up those typedefs so that the casting
    > done in main is not required?[/color]

    No. Start at f1. f1 returns a pointer to the type of f2.
    f2 returns the type of f1, i.e. a pointer to a function
    returning the type of f2, ....
    The only answer is a generic function pointer type, which
    C does not have.

    So, the only thing you can do portably is

    #include <stdio.h>

    typedef void *(*pf_t)(void);
    typedef pf_t (*ppf_t)(void);

    void * f1(void);

    pf_t f2(void);

    void * f1(void)
    {
    static long data;
    printf("func1\n ");
    return &data;
    }

    pf_t f2(void)
    {
    printf("func2\n ");
    return &f1;
    }

    int main (void)
    {
    pf_t var1;
    ppf_t var2;

    var2 = f2;
    var1 = var2();
    printf("%p\n", var1());

    return 0;
    }

    which is not what you want.[color=blue]
    > =============== =============== ===
    > #include <stdio.h>
    >
    > typedef void* p_t;[/color]

    Note: Sometimes, one sees
    typedef void *(*p_t)();
    or
    typedef int (*p_t)();
    as stand-in for a generic function pointer type.
    It does not make the casts unnecessary but "is
    at least a function pointer type".
    [color=blue]
    > typedef void (*pf_t)(void);
    > typedef pf_t (*ppf_t)(void);
    >
    > p_t f1(void);
    > p_t f2(void);
    >
    > p_t f1(void)
    > {
    > printf("func1\n ");
    > return f2;[/color]

    Every standard conforming compiler worth its salt will
    warn you in this place. Keep the warning -- when migrating
    to another compiler, operating system, or platform, it
    reminds you to rethink your choice of p_t.
    [color=blue]
    > }
    > p_t f2(void)
    > {
    > printf("func2\n ");
    > return f1;
    > }
    >
    > int main (void)
    > {
    > ppf_t var;
    >
    > var = (ppf_t)f1;
    > var = (ppf_t)var();
    > var = (ppf_t)var();
    > var = (ppf_t)var();
    >
    > return 0;
    > }
    > =============== =============== ===
    >
    > The output is:
    > func1
    > func2
    > func1[/color]

    Cheers
    Michael
    --
    E-Mail: Mine is an /at/ gmx /dot/ de address.

    Comment

    • Rod Pemberton

      #3
      Re: functions that return pointer to function


      <msolem@linuxma il.org> wrote in message
      news:1141503552 .624767.214020@ v46g2000cwv.goo glegroups.com.. .[color=blue]
      > I have some code where there are a set of functions that return
      > pointers to each other. I'm having a bit of a hard time figuring out
      > the correct type to use to do that.
      >
      > The code below works but I'm defining the functions as void*, and then
      > casting when I use them. This code is going into a general purpose
      > framework, and it would be much nicer if the user didn't need to do
      > any casting.
      >
      > Can someone tell me how to set up those typedefs so that the casting
      > done in main is not required?[/color]

      This eliminates your casting. If it doesn't work with your compiler, see
      Michael Mair's comments. I commentd out your original code with '#if 0'
      '#endif'. Hint: compare the new pf_t with f1.

      #include <stdio.h>

      typedef void* p_t;
      #if 0
      typedef void (*pf_t)(void);
      typedef pf_t (*ppf_t)(void);
      #endif
      typedef p_t (*pf_t)(void);

      p_t f1(void);
      p_t f2(void);

      p_t f1(void)
      {
      printf("func1\n ");
      return f2;
      }
      p_t f2(void)
      {
      printf("func2\n ");
      return f1;
      }

      int main (void)
      {
      #if 0
      ppf_t var;
      #endif
      pf_t var;

      #if 0
      var = (ppf_t)f1;
      var = (ppf_t)var();
      var = (ppf_t)var();
      var = (ppf_t)var();
      #endif
      var = f1;
      var = var();
      var = var();
      var = var();

      return 0;
      }


      Rod Pemberton


      Comment

      • Chris Torek

        #4
        Re: functions that return pointer to function

        >msolem@linuxma il.org schrieb:[color=blue][color=green]
        >> I have some code where there are a set of functions that return
        >> pointers to each other. I'm having a bit of a hard time figuring out
        >> the correct type to use to do that.[/color][/color]

        In article <46vpcvFd4goiU1 @individual.net >
        Michael Mair <Michael.Mair@i nvalid.invalid> wrote:[color=blue]
        >There is none. At least not in portable C.[/color]

        There is no *direct* type, at least.

        [snippage]
        [color=blue]
        >Start at f1. f1 returns a pointer to the type of f2.
        >f2 returns the type of f1, i.e. a pointer to a function
        >returning the type of f2, ....
        >The only answer is a generic function pointer type, which
        >C does not have.[/color]

        Alternatively, you can wrap these things up inside "struct"s:

        #include <stdio.h>

        struct func {
        struct func (*fp)(void);
        };

        struct func f1(void), f2(void);

        struct func f1(void) {
        struct func val;

        puts("in f1");
        val.fp = f2;
        return val;
        }

        struct func f2(void) {
        struct func val;

        puts("in f2");
        val.fp = f1;
        return val;
        }

        int main(void) {
        struct func f = { f1 };
        int i;

        for (i = 0; i < 5; i++)
        f = f.fp();
        return 0;
        }

        (or, do the same as the above but change "struct func" to
        "struct func *" in all the obvious places, make f point to one,
        and make the "val"s in each function static and return their
        addresses; or pass a pointer to the "struct func" object to
        each function and have it update f->fp; etc.).

        The OP's method (having functions return "pointer to function (args)
        returning T" for some valid type T, then using casting to make it all
        work out) is OK, if a bit error-prone. In particular, casting tends
        to make the compiler shut up even if the cast is wrong, so you have
        to very sure that every cast is really correct.
        --
        In-Real-Life: Chris Torek, Wind River Systems
        Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
        email: forget about it http://web.torek.net/torek/index.html
        Reading email is like searching for food in the garbage, thanks to spammers.

        Comment

        • msolem@linuxmail.org

          #5
          Re: functions that return pointer to function

          Thank you everybody. This has been very helpfull.

          Mike

          Comment

          Working...