function definitions

Discussion in 'C Programming' started by borophyll@gmail.com, Sep 26, 2007.

  1. Guest

    I don't understand the difference between these two declarations

    int foo(char a, char b)
    {
    ...
    }

    int foo(a, b)
    char a, b;
    {
    ...
    }

    What is the usefulness of the second form? Is there any difference?

    Secondly, I notice that if a declaration list is not included
    following an identifier list, gcc warns that the types of all the
    identifiers will default to int. Is there somewhere in the spec that
    states a default type given to identifiers if it is not explicit? If
    so, can someone please give me a pointer to the section? Or is this
    just a gcc extension/assumption?

    Regards,
    B.
     
    , Sep 26, 2007
    #1
    1. Advertising

  2. writes:
    > I don't understand the difference between these two declarations
    >
    > int foo(char a, char b)


    This is a prototype.

    > {
    > ...
    > }
    >
    > int foo(a, b)
    > char a, b;


    This is an old-style declaration, sometimes called "K&R style" because
    it's used in the first edition K&R (Kernighan & Ritchie, _The C
    Programming Language_.

    > {
    > ...
    > }
    >
    > What is the usefulness of the second form? Is there any difference?


    K&R style function declarations are effectively obsolescent, though
    they're still legal. Prior to the first ANSI C standard, in 1989,
    they were the only form available, but the standardization committee
    borrowed the first form (prototypes) from an early version of C++.

    It's useful to recognize K&R style declarations when you encounter
    them in old code, but you should never use them in new code (unless,
    for some strange reason, you need to support an ancient compiler).

    In this particular case, there's another difference. Due to argument
    promotions, the parameters in the K&R declaration are really of type
    int. The parameters in the prototype really are of type char.

    > Secondly, I notice that if a declaration list is not included
    > following an identifier list, gcc warns that the types of all the
    > identifiers will default to int. Is there somewhere in the spec that
    > states a default type given to identifiers if it is not explicit? If
    > so, can someone please give me a pointer to the section? Or is this
    > just a gcc extension/assumption?


    Implicit int was removed from the language in the 1999 standard (but
    few compilers fully support C99, and most or all compilers still
    permit implicit int in some mode).

    Don't use it. The time you save by not typing "int" isn't worth the
    headache of wondering whether it's legal to leave it out.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Sep 26, 2007
    #2
    1. Advertising

  3. John Bode Guest

    On Sep 25, 7:08 pm, wrote:
    > I don't understand the difference between these two declarations
    >
    > int foo(char a, char b)
    > {
    > ...
    >
    > }
    >
    > int foo(a, b)
    > char a, b;
    > {
    > ...
    >
    > }
    >
    > What is the usefulness of the second form? Is there any difference?


    The second form is outdated, and should no longer be used.

    >
    > Secondly, I notice that if a declaration list is not included
    > following an identifier list, gcc warns that the types of all the
    > identifiers will default to int. Is there somewhere in the spec that
    > states a default type given to identifiers if it is not explicit? If
    > so, can someone please give me a pointer to the section? Or is this
    > just a gcc extension/assumption?
    >


    I can't remember off the top of my head, but it doesn't matter,
    because you're not going to use it.

    > Regards,
    > B.
     
    John Bode, Sep 26, 2007
    #3
  4. Guest

    On Sep 26, 10:08 am, wrote:
    > I don't understand the difference between these two declarations
    >
    > int foo(char a, char b)
    > {
    > ...
    >
    > }
    >
    > int foo(a, b)
    > char a, b;
    > {
    > ...
    >
    > }
    >
    > What is the usefulness of the second form? Is there any difference?
    >
    > Secondly, I notice that if a declaration list is not included
    > following an identifier list, gcc warns that the types of all the
    > identifiers will default to int. Is there somewhere in the spec that
    > states a default type given to identifiers if it is not explicit? If
    > so, can someone please give me a pointer to the section? Or is this
    > just a gcc extension/assumption?
    >
    > Regards,
    > B.


    Thanks for the info, I guessed it was an old obsolescent form, and had
    this confirmed after rereading it and seeing the footnote which
    directed me to the following two sections:

    6.11.6 Function declarators
    The use of function declarators with empty parentheses (not prototype-
    format parameter type declarators) is an obsolescent feature.

    6.11.7 Function definitions
    The use of function definitions with separate parameter identifier and
    declaration lists (not prototype-format parameter type and identifier
    declarators) is an obsolescent feature.

    Reading 6.11.6 reads to me that function declarators with an empty
    parameter list will become obsolete, except if the function declarator
    is a prototype. In other words, you can have

    int foo();

    but not

    int foo(){ ... }

    which should be written as int foo(void){ ... }. Is this correct?
    and if so, why do we allow parameterless prototypes? What are they
    useful for? The only reason I can think is to link to some external
    definition of a function whose parameters are unknown, but in what
    case would you want to call a function with an unknown number and type
    of parameters?

    Regards,
    B.
     
    , Sep 26, 2007
    #4
  5. pete Guest

    Keith Thompson wrote:
    >
    > writes:
    > > I don't understand the difference between these two declarations
    > >
    > > int foo(char a, char b)

    >
    > This is a prototype.
    >
    > > {
    > > ...
    > > }
    > >
    > > int foo(a, b)
    > > char a, b;

    >
    > This is an old-style declaration, sometimes called "K&R style" because
    > it's used in the first edition K&R (Kernighan & Ritchie, _The C
    > Programming Language_.
    >
    > > {
    > > ...
    > > }
    > >
    > > What is the usefulness of the second form? Is there any difference?

    >
    > K&R style function declarations are effectively obsolescent, though
    > they're still legal. Prior to the first ANSI C standard, in 1989,
    > they were the only form available, but the standardization committee
    > borrowed the first form (prototypes) from an early version of C++.
    >
    > It's useful to recognize K&R style declarations when you encounter
    > them in old code, but you should never use them in new code (unless,
    > for some strange reason, you need to support an ancient compiler).
    >
    > In this particular case, there's another difference. Due to argument
    > promotions, the parameters in the K&R declaration are really of type
    > int. The parameters in the prototype really are of type char.


    What do you mean?
    Argument promotions apply to arguments, not parameters.

    /* BEGIN new.c */

    #include <stdio.h>

    int foo(a, b)
    char a, b;
    {
    return printf("sizeof a is %u\n", (unsigned)sizeof a);
    }

    int main(void)
    {
    foo(0,0);
    return 0;
    }

    /* END new.c */

    --
    pete
     
    pete, Sep 26, 2007
    #5
  6. pete <> writes:
    > Keith Thompson wrote:
    >> writes:
    >> > I don't understand the difference between these two declarations
    >> >
    >> > int foo(char a, char b)

    >>
    >> This is a prototype.
    >>
    >> > {
    >> > ...
    >> > }
    >> >
    >> > int foo(a, b)
    >> > char a, b;

    >>
    >> This is an old-style declaration, sometimes called "K&R style" because
    >> it's used in the first edition K&R (Kernighan & Ritchie, _The C
    >> Programming Language_.
    >>
    >> > {
    >> > ...
    >> > }

    [...]
    >> In this particular case, there's another difference. Due to argument
    >> promotions, the parameters in the K&R declaration are really of type
    >> int. The parameters in the prototype really are of type char.

    >
    > What do you mean?
    > Argument promotions apply to arguments, not parameters.
    >
    > /* BEGIN new.c */
    >
    > #include <stdio.h>
    >
    > int foo(a, b)
    > char a, b;
    > {
    > return printf("sizeof a is %u\n", (unsigned)sizeof a);
    > }
    >
    > int main(void)
    > {
    > foo(0,0);
    > return 0;
    > }
    >
    > /* END new.c */


    (The above program prints "sizeof a is 1".)

    You're right, I was confused. I remembered that mechanically
    converting old-style declarations to prototypes can cause problems for
    parameters of integer types narrower than int and floating-point types
    narrower than double, but I drew the wrong conclusion.

    If you pass arguments of type char to foo, they'll be promoted to int
    (because the parameter type information isn't available at the point
    of the call), and then reconverted back to char. Because of this,
    back in the Old Days, parameters of types that are subject to
    promotion were generally discouraged.

    With a prototype, char arguments are simply passed and stored as type
    char.

    My poor excuse is that I haven't had to use old-style function
    declarations in a long time. I *think* I've got it right this time.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Sep 26, 2007
    #6
  7. [comp.lang.c] Keith Thompson <> wrote:

    > K&R style function declarations are effectively obsolescent, though
    > they're still legal.


    And not even deprecated, right? I suppose one day C will lose enough
    of these legacy features to make the IOCCC obsolete, but I suspect
    I will be long dead (and I'm 27 <g>).

    --
    C. Benson Manica | I appreciate all corrections, polite or otherwise.
    cbmanica(at)gmail.com |
    ----------------------| I do not currently read any posts posted through
    sdf.lonestar.org | Google groups, due to rampant unchecked spam.
     
    Christopher Benson-Manica, Sep 26, 2007
    #7
  8. Christopher Benson-Manica <> writes:
    > [comp.lang.c] Keith Thompson <> wrote:
    >> K&R style function declarations are effectively obsolescent, though
    >> they're still legal.

    >
    > And not even deprecated, right? I suppose one day C will lose enough
    > of these legacy features to make the IOCCC obsolete, but I suspect
    > I will be long dead (and I'm 27 <g>).


    C99 6.11.7:

    The use of function definitions with separate parameter identifier
    and declaration lists (not prototype-format parameter type and
    identifier declarators) is an obsolescent feature.

    The introduction to the standard says:

    Certain features are obsolescent, which means that they may be
    considered for withdrawal in future revisions of this
    International Standard. They are retained because of their
    widespread use, but their use in new implementations (for
    implementation features) or new programs (for language [6.11] or
    library features [7.26]) is discouraged.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Sep 26, 2007
    #8
  9. On Wed, 26 Sep 2007 01:40:42 -0000, wrote:
    <snip: K&R1 format>
    > Thanks for the info, I guessed it was an old obsolescent form, and had
    > this confirmed after rereading it and seeing the footnote which
    > directed me to the following two sections:
    >
    > 6.11.6 Function declarators
    > The use of function declarators with empty parentheses (not prototype-
    > format parameter type declarators) is an obsolescent feature.
    >
    > 6.11.7 Function definitions
    > The use of function definitions with separate parameter identifier and
    > declaration lists (not prototype-format parameter type and identifier
    > declarators) is an obsolescent feature.
    >
    > Reading 6.11.6 reads to me that function declarators with an empty
    > parameter list will become obsolete, except if the function declarator
    > is a prototype. In other words, you can have
    >
    > int foo();
    >
    > but not
    >
    > int foo(){ ... }
    >
    > which should be written as int foo(void){ ... }. Is this correct?


    No. In C, a function declarator with empty parentheses is not a
    prototype. The parenthesised(!) clauses in 6.11.6,7 are (additional)
    explanations of the statements NOT limitations on their applicability.
    <OT> C++ is different: K&R1 style is dropped, ALL function declarators
    have prototype syntax and semantics, and empty parentheses mean no
    parameters. In C++ you MAY also use (void) to mean explicitly zero
    parameters, in C you MUST use it to get that meaning. </>

    <snip points that depend on false assumption>

    Nit: it doesn't actually say they 'will' become obsolete, or more
    specifically that they will be deleted. It says they _may_, and some
    people believe they _should_, but AFAICT the standards process does
    not allow a binding commitment to future action. But for the reasons
    already discussed, you should avoid them even if they aren't deleted.

    - formerly david.thompson1 || achar(64) || worldnet.att.net
     
    David Thompson, Oct 8, 2007
    #9
    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. Hongzheng Wang
    Replies:
    8
    Views:
    309
    Irrwahn Grausewitz
    Jun 9, 2004
  2. Hallvard B Furuseth

    imports after function definitions?

    Hallvard B Furuseth, Aug 28, 2003, in forum: Python
    Replies:
    4
    Views:
    332
    Hallvard B Furuseth
    Sep 1, 2003
  3. Joerg Schuster
    Replies:
    14
    Views:
    535
    Joerg Schuster
    Nov 11, 2003
  4. Fred Ma
    Replies:
    8
    Views:
    349
    Fred Ma
    Apr 13, 2004
  5. Raymond Tinsel

    Hide module function definitions

    Raymond Tinsel, Jun 15, 2004, in forum: Python
    Replies:
    2
    Views:
    323
    A. Lloyd Flanagan
    Jun 15, 2004
Loading...

Share This Page