Function pointer array as parameter to a function

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • aruna.mysore@gmail.com

    Function pointer array as parameter to a function

    Hi all,

    I have a specific problem passing a function pointer array as a
    parameter to a function. I am trying to use a function which takes a
    function pointer array as an argument. I am too sure about the syntax
    of calling the same.

    #include <stdio.h>

    void fp1()
    { printf("In fp1\n"); }

    void fp2()
    { printf("In fp2\n");}

    void fp3()
    { printf("In fp3\n");}

    void call_fpn(void (*fp[3])())
    {
    (*fp[0])();
    (*fp[1])();
    (*fp[2])();
    }

    void main()
    {
    void (*pfn[3])()={NULL};
    pfn[0]=&fp1;
    pfn[1]=&fp2;
    pfn[2]=&fp3;

    call_fpn(.....) ;
    }

    Can someone please let me know what is the right syntax for calling
    the function accepting a function pointer array.

    Thanks in advance.
    Ar
  • Pietro Cerutti

    #2
    Re: Function pointer array as parameter to a function

    runa.mysore@gma il.com wrote:
    Hi all,
    >
    I have a specific problem passing a function pointer array as a
    parameter to a function. I am trying to use a function which takes a
    function pointer array as an argument. I am too sure about the syntax
    of calling the same.
    >
    #include <stdio.h>
    >
    void fp1()
    { printf("In fp1\n"); }
    >
    void fp2()
    { printf("In fp2\n");}
    >
    void fp3()
    { printf("In fp3\n");}
    >
    void call_fpn(void (*fp[3])())
    {
    (*fp[0])();
    (*fp[1])();
    (*fp[2])();
    }
    >
    void main()
    {
    void (*pfn[3])()={NULL};
    pfn[0]=&fp1;
    pfn[1]=&fp2;
    pfn[2]=&fp3;
    >
    call_fpn(.....) ;
    }
    >
    Can someone please let me know what is the right syntax for calling
    the function accepting a function pointer array.
    Isn't

    call_fpn(pfn);

    enough?
    >
    Thanks in advance.
    Ar

    --
    Pietro Cerutti

    Comment

    • vippstar@gmail.com

      #3
      Re: Function pointer array as parameter to a function

      On May 19, 4:18 pm, aruna.mys...@gm ail.com wrote:
      Hi all,
      >
      I have a specific problem passing a function pointer array as a
      parameter to a function. I am trying to use a function which takes a
      function pointer array as an argument. I am too sure about the syntax
      of calling the same.
      <snip c code>
      Can someone please let me know what is the right syntax for calling
      the function accepting a function pointer array.

      #include <stdio.h>

      #define foo() printf("%s\n", __func__)

      void f1() { foo(); }
      void f2() { foo(); }
      void f3() { foo(); }
      void doit(void (**f)()) {
      size_t i;

      for(i = 0; f[i]; f[i++]())
      ;
      }

      int main(void) {

      void (*f[4])() = {0};

      f[0] = f1;
      f[1] = f2;
      f[2] = f3;

      doit(f);

      return 0;
      }

      Comment

      • Jens Thoms Toerring

        #4
        Re: Function pointer array as parameter to a function

        aruna.mysore@gm ail.com wrote:
        I have a specific problem passing a function pointer array as a
        parameter to a function. I am trying to use a function which takes a
        function pointer array as an argument. I am too sure about the syntax
        of calling the same.
        You're attempt already looks rather good.
        #include <stdio.h>
        void fp1()
        I think it's better to exactly specify the the types of arguments
        (or that no argument is to be expected):

        void fp1( void )
        { printf("In fp1\n"); }
        void fp2()
        { printf("In fp2\n");}
        void fp3()
        { printf("In fp3\n");}
        void call_fpn(void (*fp[3])())
        {
        (*fp[0])();
        (*fp[1])();
        (*fp[2])();
        }
        You can simplify that to

        void call_fpn( void ( * fp[ 3 ] )( void ) )
        {
        fp[ 0 ]( );
        fp[ 1 ]( );
        fp[ 2 ]( );
        }

        A function pointer followed by parentheses does call the function,
        no need to dereference the pointer.

        And if you don't want to restrict yourself to an array of
        fixed size just use

        void call_fpn( void ( ** fp )( void ) )
        void main()
        main() always returns an int, so make that

        int main( void )
        {
        void (*pfn[3])()={NULL};
        You can do the initialization already with the definition:

        void ( * pfn[ 3 ] )( void ) = { fp1, fp2, fp3 };
        pfn[0]=&fp1;
        The name of the function alone is already a pointer to the
        function (at least when it's used as a value), so the '&'
        isn't necessary.
        pfn[1]=&fp2;
        pfn[2]=&fp3;
        call_fpn(.....) ;
        Just pass 'pfn' as the argument:

        call_fpn( pfn );

        return 0;
        }
        Regards, Jens
        --
        \ Jens Thoms Toerring ___ jt@toerring.de
        \______________ ____________ http://toerring.de

        Comment

        • vippstar@gmail.com

          #5
          Re: Function pointer array as parameter to a function

          On May 19, 4:50 pm, j...@toerring.d e (Jens Thoms Toerring) wrote:
          aruna.mys...@gm ail.com wrote:
          I have a specific problem passing a function pointer array as a
          parameter to a function. I am trying to use a function which takes a
          function pointer array as an argument. I am too sure about the syntax
          of calling the same.
          >
          You're attempt already looks rather good.
          >
          #include <stdio.h>
          void fp1()
          >
          I think it's better to exactly specify the the types of arguments
          (or that no argument is to be expected):
          >
          void fp1( void )
          >
          { printf("In fp1\n"); }
          void fp2()
          { printf("In fp2\n");}
          void fp3()
          { printf("In fp3\n");}
          void call_fpn(void (*fp[3])())
          {
          (*fp[0])();
          (*fp[1])();
          (*fp[2])();
          }
          >
          You can simplify that to
          >
          void call_fpn( void ( * fp[ 3 ] )( void ) )
          {
          fp[ 0 ]( );
          fp[ 1 ]( );
          fp[ 2 ]( );
          >
          }
          >
          A function pointer followed by parentheses does call the function,
          no need to dereference the pointer.
          >
          And if you don't want to restrict yourself to an array of
          fixed size just use
          He isn't. The [3] really is just informative, but actually a pointer.
          <snip>

          Comment

          • Jens Thoms Toerring

            #6
            Re: Function pointer array as parameter to a function

            vippstar@gmail. com wrote:
            On May 19, 4:50 pm, j...@toerring.d e (Jens Thoms Toerring) wrote:

            void call_fpn( void ( * fp[ 3 ] )( void ) )

            And if you don't want to restrict yourself to an array of
            fixed size just use
            He isn't. The [3] really is just informative, but actually a pointer.
            Of course, you're right.
            Regards, Jens
            --
            \ Jens Thoms Toerring ___ jt@toerring.de
            \______________ ____________ http://toerring.de

            Comment

            • Bart

              #7
              Re: Function pointer array as parameter to a function

              On May 19, 2:50 pm, j...@toerring.d e (Jens Thoms Toerring) wrote:
              aruna.mys...@gm ail.com wrote:
              >
              You can simplify that to
              void call_fpn( void ( * fp[ 3 ] )( void ) )
              You seem to be quite good at this:

              Consider that parameter type, call it T:

              void (*fp[3])void

              How could I modify T to end up with an array [N] of T?

              How could I modify T to have a pointer to T?

              How could I modify T to have a function returning type T?

              Please add any parentheses that might be needed.

              (I need ask a similar question in a different guise recently. But no
              replies, so it was either incredibly difficult, or so trivial that
              nobody could understand why I was even asking. I contrived a solution
              of sorts but it was unsatisfactory. )

              -- Thanks,

              Bartc

              Comment

              • Jens Thoms Toerring

                #8
                Re: Function pointer array as parameter to a function

                Bart <bc@freeuk.comw rote:
                On May 19, 2:50 pm, j...@toerring.d e (Jens Thoms Toerring) wrote:
                aruna.mys...@gm ail.com wrote:

                You can simplify that to
                void call_fpn( void ( * fp[ 3 ] )( void ) )
                Consider that parameter type, call it T:
                void (*fp[3])void
                I guess you meant

                void (*fp[3])( void )
                How could I modify T to end up with an array [N] of T?
                How could I modify T to have a pointer to T?
                How could I modify T to have a function returning type T?
                I am not sure if I understand your questions correctly, so
                what I write in the following might be completely off the
                mark...

                First thing I would consider when things get too complicated
                is using a typedef for the type of function pointer passed
                around, e.g.

                typedef void ( * func_t )( void );

                'func_t' is now a new type that is a pointer to a function
                which takes no arguments and returns nothing.

                Now you can e.g. write the call_fpn() function as

                void call_fpn( func_t fp[ 3 ] )

                which already looks a lot more readable.

                As someone else already has pointed out the '[3]' bit isn't
                really relevant, what the function receives is a pointer to
                the first element of an array of function pointers. So you
                could also write that as

                void call_fpn( func_t fp[ ] )

                or

                void call_fpn( func_t *fp )

                If you now want the call_fpn() function to return a function
                pointer of the same type as the ones in the array it got
                passed then just change it to e.g.

                func_t call_fpn( func_t *fp )
                {
                fp[ 0 ]( );
                fp[ 1 ]( );
                return fp[ 2 ];
                }

                Then you can do in main() e.g.

                int main( void )
                {
                funct_t pfn[ 3 ] = { fp1, fp2, fp3 }
                call_fpn( pfn )( );
                return 0;
                }

                This will result in fp1() and fp2() getting called from within
                call_fpn() and then the function returned by call_fpn(), fp3,
                being called from within main().

                If you insist on not using a typedef things will look a lot
                uglier. E.g. call_fpn() then would have to be defined instead
                of

                func_t call_fpn( func_t *fp )

                as

                void ( * call_fpn( void ( ** fp )( void ) ) )( void )

                (I hope I got that right, at least the compiler doesn't com-
                plain;-) which I find extremely hard to understand...

                Does that about answer what you asked? Otherwise please help
                me by trying to describe the problem a bit differently.

                Regards, Jens
                --
                \ Jens Thoms Toerring ___ jt@toerring.de
                \______________ ____________ http://toerring.de

                Comment

                • Keith Thompson

                  #9
                  Re: Function pointer array as parameter to a function

                  aruna.mysore@gm ail.com writes:
                  I have a specific problem passing a function pointer array as a
                  parameter to a function. I am trying to use a function which takes a
                  function pointer array as an argument. I am too sure about the syntax
                  of calling the same.
                  [...]

                  You can't. In C, a function cannot take an array as a parameter.

                  It can *appear* to do so:

                  void func(int arr[]);

                  ...

                  int my_array[42];
                  func(my_array);

                  but in fact the parameter "arr" is just a pointer, and the argument
                  "my_array" is implicitly *converted* to a pointer (to the first
                  element of the array) when it's evaluated.

                  See section 6 of the comp.lang.c FAQ, <http://www.c-faq.com/>.

                  --
                  Keith Thompson (The_Other_Keit h) kst-u@mib.org <http://www.ghoti.net/~kst>
                  Nokia
                  "We must do something. This is something. Therefore, we must do this."
                  -- Antony Jay and Jonathan Lynn, "Yes Minister"

                  Comment

                  • aruna.mysore@gmail.com

                    #10
                    Re: Function pointer array as parameter to a function

                    Hi all,

                    Thank you everyone for your time and responses.

                    Thanks and Regards,
                    Ar

                    Comment

                    • Bart

                      #11
                      Re: Function pointer array as parameter to a function

                      On May 19, 4:58 pm, j...@toerring.d e (Jens Thoms Toerring) wrote:
                      Bart <b...@freeuk.co mwrote:
                      On May 19, 2:50 pm, j...@toerring.d e (Jens Thoms Toerring) wrote:
                      aruna.mys...@gm ail.com wrote:
                      >
                      You can simplify that to
                      void call_fpn( void ( * fp[ 3 ] )( void ) )
                      Consider that parameter type, call it T:
                      void (*fp[3])void
                      >
                      I guess you meant
                      >
                      void (*fp[3])( void )
                      Yes.
                      >
                      How could I modify T to end up with an array [N] of T?
                      How could I modify T to have a pointer to T?
                      How could I modify T to have a function returning type T?
                      >
                      I am not sure if I understand your questions correctly, so
                      what I write in the following might be completely off the
                      mark...
                      ...
                      void ( * call_fpn( void ( ** fp )( void ) ) )( void )
                      >
                      (I hope I got that right, at least the compiler doesn't com-
                      plain;-) which I find extremely hard to understand...
                      >
                      Does that about answer what you asked? Otherwise please help
                      me by trying to describe the problem a bit differently.
                      I find C types incomprehensibl e other than the simplest.

                      So I was after a way of simply building up a complex type step by
                      step, working from an left-to-right description in English. And
                      starting from a non-trivial type so that I can see how you place any
                      new stuff in relation to *, [] and ().

                      Typedefs are also a useful build tool but I think I need to be able
                      build types out of primary elements first. This is for both straight
                      coding, and machine-generated code when readability isn't so
                      important.

                      --
                      Bartc

                      Comment

                      • Jens Thoms Toerring

                        #12
                        Re: Function pointer array as parameter to a function

                        Bart <bc@freeuk.comw rote:
                        I find C types incomprehensibl e other than the simplest.
                        Me too;-) It's actually a lot simpler to me assembling
                        them then parsing them.
                        So I was after a way of simply building up a complex type step by
                        step, working from an left-to-right description in English.
                        At least in the more complicated cases it isn't left-to-right
                        but more like zig-zack... KR2 has some subchapter on the topic
                        (5.12) but that doesn't make it any simpler.
                        And starting from a non-trivial type so that I can see how you place any
                        new stuff in relation to *, [] and ().
                        Typedefs are also a useful build tool but I think I need to be able
                        build types out of primary elements first. This is for both straight
                        coding, and machine-generated code when readability isn't so
                        important.
                        There's a definitely a logic behind it since e.g. the cdecl program
                        can deal with such things (and the compiler, of course, also does;-).
                        If you want to machine-generate code looking at the sources of that
                        program may give you some ideas (I didn't, so I can't say how well-
                        written it is).

                        But when I have to construct something "by hand" I would start
                        with a typedef and "expand" the typedef. E.g. if you have a
                        typedef like

                        typedef void ( * func_t )( void );

                        and you want to rewrite

                        func_t call_fpn( func_t *fp )

                        in basic types I would replace the 'func_t' parts in the following
                        way

                        a) take everything from the typedef before the string 'func_t'
                        (except the 'typedef' keyword, of course) and replace the
                        occurence of 'func_t' by it.
                        b) take everything following 'func_t' in the typedef (except the
                        semicolon) and put it behind the stuff 'func_t' was applied to
                        (i.e. everything until the next unbalanced closing paranthesis
                        or the end of the declaration/function signature, whatever comes
                        first).

                        So replacing the first 'func_t' that way in

                        func_t call_fpn( func_t * fp )

                        using

                        typedef void ( * func_t )( void );
                        ^^^^^^^^ ^^^^^^^^^
                        before after

                        leads to

                        void ( * call_fpn( func_t * fp ) )( void )
                        ^^^^^^^^ ^^^^^^^^^
                        before after

                        That gets rid of the first instance of 'func_t'. The second one
                        can be replaced the same way:

                        void ( * call_fpn( void ( * * fp )( void ) ) )( void )
                        ^^^^^^^^ ^^^^^^^^^
                        before after

                        I don't know if that helps at all. But perhaps by approaching
                        the problem from the point of view that typedefs can be "ex-
                        panded" by textual replacement on the one hand and that you
                        can simplify complicated declarations with typedefs on the
                        other, leading to relatively easy to read declarations, gives
                        you some ideas of how to approach things in your program...

                        Regards, Jens
                        --
                        \ Jens Thoms Toerring ___ jt@toerring.de
                        \______________ ____________ http://toerring.de

                        Comment

                        • Bart

                          #13
                          Re: Function pointer array as parameter to a function

                          On May 20, 1:07 am, j...@toerring.d e (Jens Thoms Toerring) wrote:
                          Bart <b...@freeuk.co mwrote:
                          I find C types incomprehensibl e other than the simplest.
                          >
                          Me too;-) It's actually a lot simpler to me assembling
                          them then parsing them.
                          OK, I've come up with a technique which I think is along the lines you
                          suggested with typedefs, but was actually derived by trying lots of
                          things with cdecl!

                          This works for types that involve a name of some sort (like
                          declarations, but not casts, although I'd imagine they'd be similar).

                          * Start with any declaration that has a name, such as int x;

                          * To create an array N of that, replace the name x by (x[N])

                          * To create a pointer to that, replace the name by (*x)

                          * To create a function returning that, replace the name by (x()). (If
                          it takes parameters, put those inside the ().)

                          With the capability of stacking these to any extent. However there are
                          likely superfluous parentheses in there rendering the result, for
                          complex cases, even more unreadable.

                          To try this on the OP's problem, he first wanted an Array 3 of Pointer
                          to Function taking () and returning Void. Hmmm, I think you have to go
                          right to left with this:

                          void x

                          Now add a function returning that:

                          void (x()) /* already it's clear the outer () not needed) */

                          Now a pointer to that, following my rules:

                          void ((*x)())

                          Finally, an array[3] of that:

                          void ((*(x[3]))())

                          And his call_fpn() function I think wanted a pointer to that lot,
                          namely:

                          void ((*((*x)[3]))()) /* the 3 not useful here */

                          --
                          Bartc

                          Comment

                          • Bart

                            #14
                            Re: Function pointer array as parameter to a function

                            On May 20, 4:10 am, Bart <b...@freeuk.co mwrote:

                            I've streamlined the processs to construct arbitrary C type
                            declarations from English, to avoid extra parentheses:

                            * Start with any declaration that has a name, such as int x;

                            * To create an array N of that, replace the name x by x[N] or (x[N])

                            * To create a pointer to that, replace the name x by (*x), although
                            when x already has * on it's left, the parentheses are not needed.

                            * To create a function returning that, replace the name x by x() or
                            (x()). Any parameter types go inside the ().

                            (Using the same logic in reverse, it's even possible for a human to
                            actually figure out what a complex declaration does! But really it
                            shouldn't be necessary to go to all this trouble..)

                            I'm having trouble however building cast types using this method.

                            I've tried doing the above using a dummy name, which is then removed
                            and the whole thing enclosed in parentheses. And I've tried keeping
                            the original extra parentheses around each extra addition.

                            But cdecl is temperamental on these and compilers don't generally tell
                            you the exact meaning of the type; only lccwin spells it out in
                            English but it doesn't always correspond to what I think.

                            So what is the normal technique for a type specification to be
                            converted from declarative form to a cast?

                            --
                            Bartc

                            Comment

                            • Nick Keighley

                              #15
                              Re: Function pointer array as parameter to a function

                              On 20 May, 14:48, Bart <b...@freeuk.co mwrote:
                              On May 20, 4:10 am, Bart <b...@freeuk.co mwrote:
                              I've streamlined the processs to construct arbitrary C type
                              declarations from English, to avoid extra parentheses:
                              >
                              * Start with any declaration that has a name, such as int x;
                              I'm not sure how this helps. Why not start with a bare
                              identifier? How does your method help with ptr-to-funcs?

                              * To create an array N of that, replace the name x by x[N] or (x[N])
                              >
                              * To create a pointer to that, replace the name x by (*x), although
                              when x already has * on it's left, the parentheses are not needed.
                              int x - int (*x)

                              this looks wrong. The easiest way is build them up in stages
                              using typedefs.

                              With function ptrs I just remember that

                              int *f ()
                              is a function returning int*

                              and
                              int (*f)()
                              is a pointer to a function returning int

                              I don't do clever things with arrays.

                              * To create a function returning that, replace the name x by x() or
                              (x()). Any parameter types go inside the ().
                              >
                              (Using the same logic in reverse, it's even possible for a human to
                              actually figure out what a complex declaration does! But really it
                              shouldn't be necessary to go to all this trouble..)
                              well it becomes necessary if someone insists on using the raw
                              declaration syntax. Can you decode this one?

                              void (*signal(int sig, void (*func)(int)))( int);

                              (assuming I copied it correctly!)

                              I'm having trouble however building cast types using this method.
                              cast types? I think the answer is typedefs again.

                              /* simple case */
                              j = (int*)n;

                              /* ptr-to function taking in tand returning void */
                              typedef void (*FP)(int);

                              /* takes an FP and returns an FP */
                              FP func_s (FP);

                              so if a cast is needed
                              func_s ((FP)something_ else);

                              I've tried doing the above using a dummy name, which is then removed
                              and the whole thing enclosed in parentheses. And I've tried keeping
                              the original extra parentheses around each extra addition.
                              >
                              But cdecl is temperamental on these and compilers don't generally tell
                              you the exact meaning of the type; only lccwin spells it out in
                              English but it doesn't always correspond to what I think.
                              >
                              So what is the normal technique for a type specification to be
                              converted from declarative form to a cast?
                              use a typedef

                              --
                              Nick Keighley


                              Comment

                              Working...