Function pointer array as parameter to a function

Discussion in 'C Programming' started by aruna.mysore@gmail.com, May 19, 2008.

  1. Guest

    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
     
    , May 19, 2008
    #1
    1. Advertising

  2. Guest

    On May 19, 4:18 pm, 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; f[i++]())
    ;
    }

    int main(void) {

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

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

    doit(f);

    return 0;
    }
     
    , May 19, 2008
    #2
    1. Advertising

  3. 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 ___
    \__________________________ http://toerring.de
     
    Jens Thoms Toerring, May 19, 2008
    #3
  4. Guest

    On May 19, 4:50 pm, (Jens Thoms Toerring) wrote:
    > 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>
     
    , May 19, 2008
    #4
  5. wrote:
    > On May 19, 4:50 pm, (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 ___
    \__________________________ http://toerring.de
     
    Jens Thoms Toerring, May 19, 2008
    #5
  6. Bart Guest

    On May 19, 2:50 pm, (Jens Thoms Toerring) wrote:
    > 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
     
    Bart, May 19, 2008
    #6
  7. Bart <> wrote:
    > On May 19, 2:50 pm, (Jens Thoms Toerring) wrote:
    > > 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 ___
    \__________________________ http://toerring.de
     
    Jens Thoms Toerring, May 19, 2008
    #7
  8. 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_Keith) <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"
     
    Keith Thompson, May 19, 2008
    #8
  9. Guest

    Hi all,

    Thank you everyone for your time and responses.

    Thanks and Regards,
    Ar
     
    , May 19, 2008
    #9
  10. Bart Guest

    On May 19, 4:58 pm, (Jens Thoms Toerring) wrote:
    > Bart <> wrote:
    > > On May 19, 2:50 pm, (Jens Thoms Toerring) wrote:
    > > > 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 incomprehensible 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
     
    Bart, May 19, 2008
    #10
  11. Bart <> wrote:
    > I find C types incomprehensible 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 ___
    \__________________________ http://toerring.de
     
    Jens Thoms Toerring, May 20, 2008
    #11
  12. Bart Guest

    On May 20, 1:07 am, (Jens Thoms Toerring) wrote:
    > Bart <> wrote:
    > > I find C types incomprehensible 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
     
    Bart, May 20, 2008
    #12
  13. Bart Guest

    On May 20, 4:10 am, Bart <> wrote:

    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
     
    Bart, May 20, 2008
    #13
  14. On 20 May, 14:48, Bart <> wrote:
    > On May 20, 4:10 am, Bart <> wrote:


    > 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
     
    Nick Keighley, May 20, 2008
    #14
  15. Bart <> writes:

    > On May 20, 4:10 am, Bart <> wrote:

    <snip>
    > 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?


    The normal rule is just to write a declaration, remove the name and
    the ; and enclose in ()s. Do you have an example where this is wrong?

    --
    Ben.
     
    Ben Bacarisse, May 20, 2008
    #15
  16. Bart Guest

    On May 20, 3:39 pm, Ben Bacarisse <> wrote:
    > Bart <> writes:
    > > On May 20, 4:10 am, Bart <> wrote:

    > <snip>
    > > 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?

    >
    > The normal rule is just to write a declaration, remove the name and
    > the ; and enclose in ()s.  Do you have an example where this is wrong?


    Now that I try to find an example, it's not so easy!

    Probably there was no actual error, apart from actual errors of syntax
    and odd things like this:

    int ((*((*(x(char)))[]))[]);
    int y;

    x = (int ((*((*((char)))[]))[]))y;

    This a type error (the type returns a function). But decl was quite
    happy with the cast when written without the 'char':

    (int ((*((*(()))[]))[]))y

    But gave a syntax error on: (int ((*((*((char)))[]))[]))y

    So just funny things with cdecl.

    --
    Bartc
     
    Bart, May 20, 2008
    #16
  17. Bart Guest

    On May 20, 3:31 pm, Nick Keighley <>
    wrote:
    > On 20 May, 14:48, Bart <> wrote:
    >
    > > On May 20, 4:10 am, Bart <> wrote:
    > > 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?


    Getting started is actually not so easy! Anyway even I can cope with
    int x, y[], *z;

    > How does your method help with ptr-to-funcs?


    If int fn(char) is a function decl then int (*fn)(char) is a pointer
    to it, according to cdecl and using my (old)rule#2.

    >
    > > * 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.


    I think my methods are wrong. I tested only on terms of types that
    were already well-specified with parentheses.

    OK, so I'll go back to my original steps and forget about avoiding
    parentheses. If the result obviously doesn't need then, as in your
    example, then they can be left out.

    >
    > 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..)


    I meant if the C type system had been done properly!

    > 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);


    No, only if written according to my rules. But I'll have a go. It
    looks like:

    void (*s()) (int)

    Which I would have to have to write as: void (*(s()))(int). By
    striking and eliminating from the inside out, I did struggle to the
    correct result. The params of s or signal are easy: each one is an
    independent type and is decoded by itself.


    >
    > > 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);


    void func_s(int) /* step 1, basic type */
    void (*func_s)(int) /* step 2, declared ptr-to-fn */
    (void (*)(int))x /* step 3, cast */

    I just wrote these myself without any help and checked with cdecl!

    In practice yes typedefs can be used but I need to understand this
    basic stuff first.

    --
    Bartc
     
    Bart, May 20, 2008
    #17
  18. Guest

    On May 20, 6:25 pm, Bart <> wrote:
    > On May 20, 3:39 pm, Ben Bacarisse <> wrote:
    >
    >
    >
    > > Bart <> writes:
    > > > On May 20, 4:10 am, Bart <> wrote:

    > > <snip>
    > > > 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?

    >
    > > The normal rule is just to write a declaration, remove the name and
    > > the ; and enclose in ()s. Do you have an example where this is wrong?

    Functions, you need to add an extra asterisk (*), ie
    int foo(int);
    int (*)(int)
    > Now that I try to find an example, it's not so easy!
    >
    > Probably there was no actual error, apart from actual errors of syntax
    > and odd things like this:
    >
    > int ((*((*(x(char)))[]))[]);

    Why the redundant parenthesis?
    That's equivalent to int (*(*x(char))[])[], and what the function
    returns is a pointer to an incomplete array of pointers to incomplete
    arrays of int.
    > int y;
    >
    > x = (int ((*((*((char)))[]))[]))y;

    x is a function, you cannot assign to it.
    >
    > This a type error (the type returns a function). But decl was quite
    > happy with the cast when written without the 'char':
    >
    > (int ((*((*(()))[]))[]))y
    >
    > But gave a syntax error on: (int ((*((*((char)))[]))[]))y
    >
    > So just funny things with cdecl.

    It's funny things with your code, nod cdecl.
     
    , May 20, 2008
    #18
  19. John Bode Guest

    On May 19, 9:09 am, Bart <> wrote:
    > On May 19, 2:50 pm, (Jens Thoms Toerring) wrote:
    >
    > > 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
    >


    void (*fp[3])(void)

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


    Well, let's make sure we understand what T is. To parse a hairy
    declaration, I start by finding the leftmost identifier, then work my
    way out, remembering that [] and () bind before *:

    fp -- fp
    fp[3] -- is a 3-element array
    *fp[3] -- of pointers
    (*fp[3])(void) -- to functions
    void (*fp[3])(void) -- returning void

    So you want an N-element array of 3-element arrays of pointers to
    functions returning void. So we build it up as follows:

    fp -- fp
    fp[N] -- is an N-element array
    fp[N][3] -- of 3-element arrays
    *fp[N][3] -- of pointers
    (*fp[N][3])(void) -- to functions
    void (*fp[N][3])(void) -- retuning void

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


    fp -- fp
    *fp -- is a pointer
    (*fp)[3] -- to a 3-element array
    *(*fp)[3] -- of pointers
    (*(*fp)[3])(void) -- to functions
    void (*(*fp)[3])(void) -- returning void

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


    fp -- fp
    fp() -- is a function
    *fp() -- returning a pointer
    (*fp())[3] -- to a 3-element array
    *(*fp())[3] -- of pointers
    (*(*fp())[3])(void) -- to functions
    void (*(*fp())[3])(void) -- returning void


    > 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


    I'm not sure when I hit on this particular system for reading and
    building hairy declarators, but I've had pretty good success with it.
    You can also try to work your way from the outside in, using
    substitution:

    void F(void) -- F = (*P)
    void (*P)(void) -- P = fp[3]
    void (*fp[3])(void)

    but I find the first method more straightforward, and more useful for
    building complex declarations.
     
    John Bode, May 20, 2008
    #19
  20. writes:

    > On May 20, 6:25 pm, Bart <> wrote:
    >> On May 20, 3:39 pm, Ben Bacarisse <> wrote:
    >>
    >>
    >>
    >> > Bart <> writes:
    >> > > On May 20, 4:10 am, Bart <> wrote:
    >> > <snip>
    >> > > 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?

    >>
    >> > The normal rule is just to write a declaration, remove the name and
    >> > the ; and enclose in ()s. Do you have an example where this is wrong?

    > Functions, you need to add an extra asterisk (*), ie
    > int foo(int);
    > int (*)(int)


    They are not the same type. The declaration with a name would be

    int (*foo)(int);

    and the "rule" correctly gives the cast operator: (int (*)(int)).

    --
    Ben.
     
    Ben Bacarisse, May 20, 2008
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. sangeetha

    Array of pointer Vs Pointer to Array

    sangeetha, Oct 8, 2004, in forum: C Programming
    Replies:
    9
    Views:
    355
    Tim Rentsch
    Oct 9, 2004
  2. erfan

    Array of pointer and pointer of array

    erfan, Jan 28, 2008, in forum: C Programming
    Replies:
    6
    Views:
    682
    Martin Ambuhl
    Jan 28, 2008
  3. RSL
    Replies:
    14
    Views:
    3,319
  4. Hansen
    Replies:
    3
    Views:
    1,121
    rep_movsd
    Apr 24, 2010
  5. , India

    pointer to an array vs pointer to pointer

    , India, Sep 20, 2011, in forum: C Programming
    Replies:
    5
    Views:
    467
    James Kuyper
    Sep 23, 2011
Loading...

Share This Page