Function declarations

Discussion in 'C Programming' started by BartC, Sep 28, 2012.

  1. BartC

    BartC Guest

    I have a C code generator that likes to insert lots of parentheses in type
    declarations (rather than truly understand how they work).

    But when declaring a function returning a pointer:

    int (*fn) (void);

    int (*fn) (void ) {return NULL;}

    the prototype works, but not the definition (it's a syntax error). How do I
    have to change the latter to make it compile?

    Everywhere else the extra parentheses don't seem to be a problem.


    Thanks.

    --
    Bartc.
     
    BartC, Sep 28, 2012
    #1
    1. Advertising

  2. "BartC" <> writes:
    > I have a C code generator that likes to insert lots of parentheses in type
    > declarations (rather than truly understand how they work).
    >
    > But when declaring a function returning a pointer:
    >
    > int (*fn) (void);
    >
    > int (*fn) (void ) {return NULL;}
    >
    > the prototype works, but not the definition (it's a syntax error). How do I
    > have to change the latter to make it compile?
    >
    > Everywhere else the extra parentheses don't seem to be a problem.


    That's not a valid function definition.

    Your first line declares an object `fn` of pointer-to-function type,
    which is perfectly valid.

    The declaration part of the function definition (the part outside
    {...}) declares a pointer-to-function type. A function definition
    has to declare something of function type, not pointer type.

    You could drop the parentheses:

    int fn(void) { return 0; }

    Note that I've changed the return expression, since NULL is normally
    used for pointers.

    Or you might have something like this:

    int func(void) { return 0; }
    int (*fn)(void) = func;

    I can't tell which of these would suit your purposes.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Will write code for food.
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Sep 28, 2012
    #2
    1. Advertising

  3. On 2012-09-28, BartC <> wrote:
    > I have a C code generator that likes to insert lots of parentheses in type
    > declarations (rather than truly understand how they work).
    >
    > But when declaring a function returning a pointer:
    >
    > int (*fn) (void);
    >
    > int (*fn) (void ) {return NULL;}
    >
    > the prototype works, but not the definition (it's a syntax error). How do I
    > have to change the latter to make it compile?


    That's not a function returning a pointer: that's a pointer to a
    function (returning int):

    $ cdecl
    int (*fn) (void);
    declare fn as pointer to function that expects (void) returning int;

    int *fn(void) { ... } will (of course) work.


    --
    Heikki Kallasjoki
     
    Heikki Kallasjoki, Sep 28, 2012
    #3
  4. "BartC" <> writes:

    > I have a C code generator that likes to insert lots of parentheses in
    > type declarations (rather than truly understand how they work).
    >
    > But when declaring a function returning a pointer:
    >
    > int (*fn) (void);


    That's not what the above does. It declares (and, at file scope,
    tentatively defines) a pointer to a function.

    > int (*fn) (void ) {return NULL;}


    Returning NULL is peculiar but fits with what you say you intended.

    > the prototype works, but not the definition (it's a syntax error). How
    > do I have to change the latter to make it compile?


    The latter, just like the former, declares a pointer, not a function.
    You'd make it work by giving it a suitable initialiser:

    int (*fn)(void) = f; /* for some f of the right type, of course */

    but it seems that you intended to write a prototype and a definition of
    a function that returns a pointer:

    int *fn(void);
    int *fn(void) { return NULL; }

    > Everywhere else the extra parentheses don't seem to be a problem.


    They aren't a problem here either, it's just that you've mistaken what
    they mean.

    There *is* a symmetry problem with C's function definitions: you can use
    a typedef of a function type to declare functions but not to define
    them. For example, if you want to declare a whole bunch of functions of
    the same type, it's easy:

    typedef int binary_operator(int, int);

    binary_operator add, sub, mul, div, rem, mod, exp;

    and the typedef comes in hand if you have (as is likely) a table of
    pointers to such functions. But when you come to define them, you can't
    use the typedef name -- you have to repeat the types:

    int add(int a, int b) { return a + b; }

    It would be nice if you could use the typedef and add just the parameter
    names. However, the "obvious" syntax is wrong:

    binary_operator add(a, b) { return a + b; }

    because binary_operator look like (well, is) the return type and not the
    function type. You'd need a new form of function definition, maybe:

    binary_operator add = (a, b) { return a + b; }

    which, at least, looks like an initialiser. Far too fiddly to parse, I
    imagine, and the use cases are too rare to register on the committee's
    radar.

    --
    Ben.
     
    Ben Bacarisse, Sep 28, 2012
    #4
  5. BartC

    BartC Guest

    "BartC" <> wrote in message news:k43ulj$v03$...
    > I have a C code generator that likes to insert lots of parentheses in type
    > declarations (rather than truly understand how they work).


    > int (*fn) (void);
    >
    > int (*fn) (void ) {return NULL;}


    OK, the replies are telling me these are both wrong! For what I'd intended
    anyway.

    The parentheses I insert automatically are needed to distinguish between:

    int *a[]; // array of pointer to int
    int *(a[]); // also array of pointer to int
    int (*a)[]; // pointer to array of int

    The code generator isn't clever enough to insert only when necessary.

    However, playing with CDECL, and using the last example above as return
    value from the function (as I want to see how parentheses work when they are
    actually needed), I ended up with:

    int (*fn(void ))[];
    int (*fn(void ))[] {return 0;};

    This last example is especially intriguing; I've never seen "[]" between a
    function parameter list and the opening "{" before!

    What this telling me though, is the parameter list needs to be taken inside
    the declaration and be attached to the name, so I will experiment with that.
    Maybe I can get to keep my parentheses.

    --
    Bartc
     
    BartC, Sep 28, 2012
    #5
  6. "BartC" <> writes:

    > "BartC" <> wrote in message news:k43ulj$v03$...
    >> I have a C code generator that likes to insert lots of parentheses
    >> in type declarations (rather than truly understand how they work).

    >
    >> int (*fn) (void);
    >>
    >> int (*fn) (void ) {return NULL;}

    >
    > OK, the replies are telling me these are both wrong! For what I'd
    > intended anyway.
    >
    > The parentheses I insert automatically are needed to distinguish between:
    >
    > int *a[]; // array of pointer to int
    > int *(a[]); // also array of pointer to int
    > int (*a)[]; // pointer to array of int
    >
    > The code generator isn't clever enough to insert only when necessary.


    I don't think that will be a problem.

    > However, playing with CDECL, and using the last example above as
    > return value from the function (as I want to see how parentheses work
    > when they are actually needed), I ended up with:
    >
    > int (*fn(void ))[];
    > int (*fn(void ))[] {return 0;};
    >
    > This last example is especially intriguing; I've never seen "[]"
    > between a function parameter list and the opening "{" before!
    >
    > What this telling me though, is the parameter list needs to be taken
    > inside the declaration and be attached to the name, so I will
    > experiment with that. Maybe I can get to keep my parentheses.


    You can keep (or add) as many parentheses as you want but I suspect your
    trouble is that you are adding them in a way that alters the intended
    meaning.

    The parameter list must be "syntactically attached" to the name but it
    can be separated from it by redundant parentheses:

    int f(void);
    int (f)(void);
    int ((f))(void);

    are all the same. The rules for reading C types help here: you read
    from the name outwards respecting balanced parentheses but otherwise
    always reading to the right before reading to the left. You stop
    reading to the right or to the left when you reach an opening or closing
    bracket (or the end of declaration). In other words you read from the
    inside out always finishing off a parenthesised part before moving on.
    When you hit the ')' at the end of a parameter list, you can say "and
    returning", otherwise just don't vocalise it:

    int (*fn(void))[];
    ^ fn is a
    ^ function taking
    ^ no arguments
    ^ and returning
    ^ (silently change direction[1])
    ^ a pointer to
    ^ (silently change direction)
    ^ an array of
    ^ (silently change direction)
    ^ int

    (This will look silly without a fixed-width font.)

    Functions can't return array types but the syntax (and these rules) let
    us know what that would look like. If at the point marked [1] we were
    to see []s instead of ')' or ';' like this:

    ... *fn(void)[] ...

    we'd have to say "and returning an array of".

    --
    Ben.
     
    Ben Bacarisse, Sep 28, 2012
    #6
  7. BartC

    Agnos Guest

    BartC wrote:
    > I have a C code generator that likes to insert lots of parentheses in
    > type declarations (rather than truly understand how they work).
    >
    > But when declaring a function returning a pointer:
    >
    > int (*fn) (void);
    >
    > int (*fn) (void ) {return NULL;}
    >
    > the prototype works, but not the definition (it's a syntax error).
    > How do I have to change the latter to make it compile?
    >
    > Everywhere else the extra parentheses don't seem to be a problem.
    >


    You worked for a BIG manufacturer, and now you are nothing but the
    throw-away slag on the molten iron of the machines that you assembled?
     
    Agnos, Oct 7, 2012
    #7
  8. BartC

    Agnos Guest

    Keith Thompson wrote:

    Who cares what he wrote? Look at his sig(!):

    > Keith Thompson (The_Other_Keith)
    > <http://www.ghoti.net/~kst>
    > Will write code for food.
    > "We must do something. This is something. Therefore, we must do this."
    > -- Antony Jay and Jonathan Lynn, "Yes Minister"


    As far as I care, until he resolves his issues, I ignore his other forays.
     
    Agnos, Oct 7, 2012
    #8
  9. BartC

    Agnos Guest

    Ben Bacarisse wrote:

    Ha! You spelled his name wrong! It's Ben Briarcase, idiot.
     
    Agnos, Oct 7, 2012
    #9
  10. On Oct 7, 6:34 am, "Agnos" <> wrote:
    > Keith Thompson wrote:


    > Who cares what he wrote? Look at his sig(!):
    >
    > > Keith Thompson (The_Other_Keith)
    > > <http://www.ghoti.net/~kst>
    > >    Will write code for food.
    > > "We must do something.  This is something.  Therefore, we must do this."
    > >    -- Antony Jay and Jonathan Lynn, "Yes Minister"

    >
    > As far as I care, until he resolves his issues, I ignore his other forays..


    what? a couple of mildly funny quotes, one from an old UK comedy
    program
     
    Nick Keighley, Oct 7, 2012
    #10
  11. On Oct 7, 6:34 am, "Agnos" <> wrote:
    > Ben Bacarisse wrote:


    > Ha! You spelled his name wrong! It's Ben Briarcase, idiot.


    PLONK
     
    Nick Keighley, Oct 7, 2012
    #11
  12. BartC

    Agnos Guest

    Nick Keighley wrote:
    > On Oct 7, 6:34 am, "Agnos" <> wrote:
    >> Keith Thompson wrote:

    >
    >> Who cares what he wrote? Look at his sig(!):
    >>
    >>> Keith Thompson (The_Other_Keith)
    >>> <http://www.ghoti.net/~kst>
    >>> Will write code for food.
    >>> "We must do something. This is something. Therefore, we must do
    >>> this." -- Antony Jay and Jonathan Lynn, "Yes Minister"

    >>
    >> As far as I care, until he resolves his issues, I ignore his other
    >> forays.

    >
    > what? a couple of mildly funny quotes, one from an old UK comedy
    > program


    Gestapo!
     
    Agnos, Oct 7, 2012
    #12
  13. BartC

    Phil Carmody Guest

    Nick Keighley <> writes:

    > On Oct 7, 6:34 am, "Agnos" <> wrote:
    > > Ben Bacarisse wrote:

    >
    > > Ha! You spelled his name wrong! It's Ben Briarcase, idiot.

    >
    > PLONK


    Just kill the header:

    Organization: Aioe.org NNTP Server

    Almost nothing of value will be lost.

    Phil
    --
    Regarding TSA regulations:
    How are four small bottles of liquid different from one large bottle?
    Because four bottles can hold the components of a binary liquid explosive,
    whereas one big bottle can't. -- camperdave responding to MacAndrew on /.
     
    Phil Carmody, Oct 14, 2012
    #13
  14. BartC

    Kaz Kylheku Guest

    On 2012-10-14, Phil Carmody <> wrote:
    > Nick Keighley <> writes:
    >
    >> On Oct 7, 6:34 am, "Agnos" <> wrote:
    >> > Ben Bacarisse wrote:

    >>
    >> > Ha! You spelled his name wrong! It's Ben Briarcase, idiot.

    >>
    >> PLONK

    >
    > Just kill the header:
    >
    > Organization: Aioe.org NNTP Server
    >
    > Almost nothing of value will be lost.


    .... says the twit posting from eternal-september.org, which is another
    free NNTP server, scarcely different from aoie.org.
     
    Kaz Kylheku, Oct 15, 2012
    #14
  15. BartC

    Armstrong Guest

    Kaz Kylheku wrote:
    > On 2012-10-14, Phil Carmody <> wrote:
    >> Nick Keighley <> writes:
    >>
    >>> On Oct 7, 6:34 am, "Agnos" <> wrote:
    >>>> Ben Bacarisse wrote:
    >>>
    >>>> Ha! You spelled his name wrong! It's Ben Briarcase, idiot.
    >>>
    >>> PLONK

    >>
    >> Just kill the header:
    >>
    >> Organization: Aioe.org NNTP Server
    >>
    >> Almost nothing of value will be lost.

    >
    > ... says the twit posting from eternal-september.org, which is another
    > free NNTP server, scarcely different from aoie.org.


    You tell him witch flag is better. I'll help you: wave a flag in a "witch's"
    face, and you will KNOW she is a witch! (History shows, such crime).
     
    Armstrong, Oct 21, 2012
    #15
    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. Dave Theese

    Local function declarations

    Dave Theese, Sep 5, 2003, in forum: C++
    Replies:
    1
    Views:
    456
    Jack Klein
    Sep 5, 2003
  2. TechCrazy

    const in function declarations

    TechCrazy, Apr 21, 2005, in forum: C++
    Replies:
    6
    Views:
    392
    Grant Schoep
    Apr 24, 2005
  3. Marcus Lessard

    Mangled function type declarations?

    Marcus Lessard, Oct 17, 2003, in forum: C Programming
    Replies:
    1
    Views:
    349
    Eric Sosman
    Oct 17, 2003
  4. Billy Patton

    Function declarations/defaults

    Billy Patton, Nov 14, 2003, in forum: C Programming
    Replies:
    17
    Views:
    546
    Chris Torek
    Nov 19, 2003
  5. Douglas
    Replies:
    2
    Views:
    335
    Herbert Rosenau
    Jul 5, 2004
Loading...

Share This Page