Why oh why does this NOT give a compile error?

Discussion in 'C Programming' started by Paul Melis, Nov 5, 2007.

  1. Paul Melis

    Paul Melis Guest

    Can someone explain to me why the following code compiles without
    errors on gcc 4.0.2?

    void f()
    {
    }

    void t()
    {
    f(1,2,3);
    f("1");
    }

    I would expect at least some warning, but not even that. Is this a
    feature of the newest C dialect or something, that you can provide
    arbitrary arguments to a function having no arguments?

    Paul

    And yes, I'm compiling the right file:

    12:58|paul@tabu:/tmp> gcc -v
    Using built-in specs.
    Target: i386-redhat-linux
    Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --
    infodir=/usr/share/info --enable-shared --enable-threads=posix --
    enable-checking=release --with-system-zlib --enable-__cxa_atexit --
    disable-libunwind-exceptions --enable-libgcj-multifile --enable-
    languages=c,c++,objc,java,f95,ada --enable-java-awt=gtk --with-java-
    home=/usr/lib/jvm/java-1.4.2-gcj-1.4.2.0/jre --host=i386-redhat-linux
    Thread model: posix
    gcc version 4.0.2 20051125 (Red Hat 4.0.2-8)
    12:58|paul@tabu:/tmp> cat t.c
    void f()
    {
    }

    void t()
    {
    f(1,2,3);
    f("1");
    }

    int
    main()
    {
    t();

    return 0;
    }
    12:58|paul@tabu:/tmp> gcc -o t -W -Wall t.c
    12:58|paul@tabu:/tmp> ls -l t
    -rwxrwxr-x 1 paul paul 4659 Nov 5 12:58 t
     
    Paul Melis, Nov 5, 2007
    #1
    1. Advertising

  2. Paul Melis

    santosh Guest

    On Monday 05 Nov 2007 5:32 pm Paul Melis <> wrote in
    article <>:

    > Can someone explain to me why the following code compiles without
    > errors on gcc 4.0.2?
    >
    > void f()
    > {
    > }
    >
    > void t()
    > {
    > f(1,2,3);
    > f("1");
    > }
    >
    > I would expect at least some warning, but not even that. Is this a
    > feature of the newest C dialect or something, that you can provide
    > arbitrary arguments to a function having no arguments?


    It's a feature of "K&R" C, i.e., a pre-Standard dialect of C. For
    backwards compatibility it is still legal though not recommended.

    An empty parameter list in a function declaration tells the compiler
    that the function takes an unspecified number and type of arguments and
    turns of parameter cross-checking of invocations against the
    declaration.

    To specify that a function accepts no arguments put the void keyword
    between the parameter list.

    void f(void) { /* ... */ }

    <snip>
     
    santosh, Nov 5, 2007
    #2
    1. Advertising

  3. "santosh" <> schrieb im Newsbeitrag
    news:fgn135$vud$...
    > On Monday 05 Nov 2007 5:32 pm Paul Melis <> wrote in
    > article <>:
    >
    >> Can someone explain to me why the following code compiles without
    >> errors on gcc 4.0.2?
    >>
    >> void f()
    >> {
    >> }
    >>
    >> void t()
    >> {
    >> f(1,2,3);
    >> f("1");
    >> }
    >>
    >> I would expect at least some warning, but not even that. Is this a
    >> feature of the newest C dialect or something, that you can provide
    >> arbitrary arguments to a function having no arguments?

    >
    > It's a feature of "K&R" C, i.e., a pre-Standard dialect of C. For
    > backwards compatibility it is still legal though not recommended.

    And therefore I'd expect at least a warning. And on my compiler I get one

    warning(229): too many arguments in function call

    Bye, Jojo
     
    Joachim Schmitz, Nov 5, 2007
    #3
  4. Paul Melis

    santosh Guest

    On Monday 05 Nov 2007 5:45 pm Joachim Schmitz <>
    wrote in article <fgn1h1$ng3$>:

    > "santosh" <> schrieb im Newsbeitrag
    > news:fgn135$vud$...
    >> On Monday 05 Nov 2007 5:32 pm Paul Melis <> wrote
    >> in article <>:
    >>
    >>> Can someone explain to me why the following code compiles without
    >>> errors on gcc 4.0.2?
    >>>
    >>> void f()
    >>> {
    >>> }
    >>>
    >>> void t()
    >>> {
    >>> f(1,2,3);
    >>> f("1");
    >>> }
    >>>
    >>> I would expect at least some warning, but not even that. Is this a
    >>> feature of the newest C dialect or something, that you can provide
    >>> arbitrary arguments to a function having no arguments?

    >>
    >> It's a feature of "K&R" C, i.e., a pre-Standard dialect of C. For
    >> backwards compatibility it is still legal though not recommended.

    > And therefore I'd expect at least a warning. And on my compiler I get
    > one
    >
    > warning(229): too many arguments in function call


    gcc needs either '-Wmissing-prototypes' or '-Wold-style-definition'
    switches to produce a diagnostic. These are not included even
    in '-Wall' and '-W'.
     
    santosh, Nov 5, 2007
    #4
  5. Paul Melis

    James Kuyper Guest

    Paul Melis wrote:
    > Can someone explain to me why the following code compiles without
    > errors on gcc 4.0.2?
    >
    > void f()
    > {
    > }
    >
    > void t()
    > {
    > f(1,2,3);
    > f("1");
    > }
    >
    > I would expect at least some warning, but not even that. Is this a
    > feature of the newest C dialect or something, that you can provide
    > arbitrary arguments to a function having no arguments?


    No, it's a feature of the C standard that this code has undefined
    behavior, but is neither a syntax error nor a constraint violation, and
    therefore does not require a diagnostic message. A good compiler might
    provide one. The more fundamental problem is that you should be using
    function prototypes, in which case the corresponding code would require
    a diagnostic message.

    What compiler options are you using? With the right compiler options,
    gcc can be a good compiler, though what it produces is a warning about
    the more fundamental problem, rather than the one you're actually asking
    about:


    cc -std=c99 -pedantic -Wall -Wpointer-arith -Wcast-align -Wwrite-strings
    -Wstrict-prototypes -Wmissing-prototypes -c -o ft.o ft.c
    ft.c:2: warning: function declaration isn’t a prototype
    ft.c:6: warning: function declaration isn’t a prototype
     
    James Kuyper, Nov 5, 2007
    #5
  6. Paul Melis

    cr88192 Guest

    "santosh" <> wrote in message
    news:fgn135$vud$...
    > On Monday 05 Nov 2007 5:32 pm Paul Melis <> wrote in
    > article <>:
    >
    >> Can someone explain to me why the following code compiles without
    >> errors on gcc 4.0.2?
    >>
    >> void f()
    >> {
    >> }
    >>
    >> void t()
    >> {
    >> f(1,2,3);
    >> f("1");
    >> }
    >>
    >> I would expect at least some warning, but not even that. Is this a
    >> feature of the newest C dialect or something, that you can provide
    >> arbitrary arguments to a function having no arguments?

    >
    > It's a feature of "K&R" C, i.e., a pre-Standard dialect of C. For
    > backwards compatibility it is still legal though not recommended.
    >
    > An empty parameter list in a function declaration tells the compiler
    > that the function takes an unspecified number and type of arguments and
    > turns of parameter cross-checking of invocations against the
    > declaration.
    >


    I guess a lot depends on if the compiler will still accept K&R style code
    (mine will not, nor will it accept some aspects of C90 syntax, such as
    'implicit int', being tolerant of missing prototypes, ...).

    of course, I am not sure whether one can view newer C dialects as infact
    proper supersets of the old dialects (say, C99 also implies full support of
    C90), or if the view is more that C in itself is actually a moving target
    (would seem at least implied), in truth several different languages that
    happen to be closly enough related that as a general rule code works between
    them without problem.

    or such...


    > To specify that a function accepts no arguments put the void keyword
    > between the parameter list.
    >
    > void f(void) { /* ... */ }
    >
    > <snip>
    >
     
    cr88192, Nov 5, 2007
    #6
  7. Paul Melis

    James Kuyper Guest

    cr88192 wrote:
    > "santosh" <> wrote in message
    > news:fgn135$vud$...
    >> On Monday 05 Nov 2007 5:32 pm Paul Melis <> wrote in
    >> article <>:
    >>
    >>> Can someone explain to me why the following code compiles without
    >>> errors on gcc 4.0.2?
    >>>
    >>> void f()
    >>> {
    >>> }
    >>>
    >>> void t()
    >>> {
    >>> f(1,2,3);
    >>> f("1");
    >>> }
    >>>
    >>> I would expect at least some warning, but not even that. Is this a
    >>> feature of the newest C dialect or something, that you can provide
    >>> arbitrary arguments to a function having no arguments?

    >> It's a feature of "K&R" C, i.e., a pre-Standard dialect of C. For
    >> backwards compatibility it is still legal though not recommended.
    >>
    >> An empty parameter list in a function declaration tells the compiler
    >> that the function takes an unspecified number and type of arguments and
    >> turns of parameter cross-checking of invocations against the
    >> declaration.
    >>

    >
    > I guess a lot depends on if the compiler will still accept K&R style code
    > (mine will not, nor will it accept some aspects of C90 syntax, such as
    > 'implicit int', being tolerant of missing prototypes, ...).


    A conforming implementation of C99 is required to accept functions
    without prototypes. But then, you've made it clear that conformance to
    any particular standard is not a priority for you.

    > of course, I am not sure whether one can view newer C dialects as infact
    > proper supersets of the old dialects (say, C99 also implies full support of
    > C90), or if the view is more that C in itself is actually a moving target
    > (would seem at least implied), in truth several different languages that
    > happen to be closly enough related that as a general rule code works between
    > them without problem.


    C99 is almost completely backwards compatible with C90, and I don't
    think this program is one of the exceptions to that rule (I can't be
    certain, I don't have a copy of the C90 standard).
     
    James Kuyper, Nov 5, 2007
    #7
  8. Paul Melis

    Guest

    On 5 Nov., 13:38, James Kuyper <> wrote:
    > Paul Melis wrote:
    > > Can someone explain to me why the following code compiles without
    > > errors on gcc 4.0.2?

    >
    > > void f()
    > > {
    > > }

    >
    > > void t()
    > > {
    > > f(1,2,3);
    > > f("1");
    > > }

    >
    > > I would expect at least some warning, but not even that. Is this a
    > > feature of the newest C dialect or something, that you can provide
    > > arbitrary arguments to a function having no arguments?

    >
    > No, it's a feature of the C standard that this code has undefined
    > behavior, but is neither a syntax error nor a constraint violation, and
    > therefore does not require a diagnostic message. A good compiler might
    > provide one. The more fundamental problem is that you should be using
    > function prototypes, in which case the corresponding code would require
    > a diagnostic message.
    >
    > What compiler options are you using? With the right compiler options,
    > gcc can be a good compiler, though what it produces is a warning about
    > the more fundamental problem, rather than the one you're actually asking
    > about:
    >
    > cc -std=c99 -pedantic -Wall -Wpointer-arith -Wcast-align -Wwrite-strings
    > -Wstrict-prototypes -Wmissing-prototypes -c -o ft.o ft.c
    > ft.c:2: warning: function declaration isn't a prototype
    > ft.c:6: warning: function declaration isn't a prototype- Zitierten Text ausblenden -
    >
    > - Zitierten Text anzeigen -



    > No, it's a feature of the C standard that this code has undefined
    > behavior, but is neither a syntax error nor a constraint violation, and
    > therefore does not require a diagnostic message.


    Exactly!
    Things that are "correct" in C might still not always be the best
    solution.

    Think about the following:

    (array == i[array]) will return (!0)
    array is the same as i[array], and it is perfectly correct in C.
    But you still would not want to use it.

    Why?
    array == *(array+i) == *(i+array) == i[array]

    Christian
     
    , Nov 5, 2007
    #8
  9. "santosh" <> wrote in message
    news:fgn135$vud$...
    > On Monday 05 Nov 2007 5:32 pm Paul Melis <> wrote in
    > article <>:
    >
    >> Can someone explain to me why the following code compiles without
    >> errors on gcc 4.0.2?
    >>
    >> void f()
    >> {
    >> }
    >>
    >> void t()
    >> {
    >> f(1,2,3);
    >> f("1");
    >> }
    >>
    >> I would expect at least some warning, but not even that. Is this a
    >> feature of the newest C dialect or something, that you can provide
    >> arbitrary arguments to a function having no arguments?

    >
    > It's a feature of "K&R" C, i.e., a pre-Standard dialect of C. For
    > backwards compatibility it is still legal though not recommended.
    >
    > An empty parameter list in a function declaration tells the compiler
    > that the function takes an unspecified number and type of
    > arguments and turns of parameter cross-checking of invocations
    > against the declaration.


    That is correct, but he provided a function _definition_, not just a
    declaration.

    > To specify that a function accepts no arguments put the void keyword
    > between the parameter list.
    >
    > void f(void) { /* ... */ }


    I thought that the "void" in the _definition_ was unnecessary; it's only
    necessary in a pure _declaration_. (Note: answer differs from C++)

    I would have expected the above behavior if he'd just provided:

    void f();

    Also, I would have expected GCC to be smart enough to realize that f(1,2,3)
    and f("1") were incompatible signatures, since f() wasn't declared as taking
    varargs, and give a warning on the second call.

    S

    --
    Stephen Sprunk "God does not play dice." --Albert Einstein
    CCIE #3723 "God is an inveterate gambler, and He throws the
    K5SSS dice at every possible opportunity." --Stephen Hawking


    --
    Posted via a free Usenet account from http://www.teranews.com
     
    Stephen Sprunk, Nov 5, 2007
    #9
  10. Paul Melis

    Flash Gordon Guest

    Stephen Sprunk wrote, On 05/11/07 15:19:
    > "santosh" <> wrote in message


    <snip>

    >> To specify that a function accepts no arguments put the void keyword
    >> between the parameter list.
    >>
    >> void f(void) { /* ... */ }

    >
    > I thought that the "void" in the _definition_ was unnecessary; it's only
    > necessary in a pure _declaration_. (Note: answer differs from C++)


    This has been argued to death both here and in comp.lang.c. Although
    "void(f() {}" defined a function that takes no parameters it does not
    provide a prototype so the compiler is not required to diagnose
    parameters being passed to it. It is, of course, *allowed* to diagnose it.

    > I would have expected the above behavior if he'd just provided:
    >
    > void f();
    >
    > Also, I would have expected GCC to be smart enough to realize that
    > f(1,2,3) and f("1") were incompatible signatures, since f() wasn't
    > declared as taking varargs, and give a warning on the second call.


    I would have said it was better for a compiler to diagnose it as well,
    but it is not a bug as such as it is not required to.
    --
    Flash Gordon
     
    Flash Gordon, Nov 5, 2007
    #10
  11. Paul Melis

    Mike Wahler Guest

    "Paul Melis" <> wrote in message
    news:...
    > Can someone explain to me why the following code compiles without
    > errors on gcc 4.0.2?
    >
    > void f()
    > {
    > }
    >
    > void t()
    > {
    > f(1,2,3);
    > f("1");
    > }
    >
    > I would expect at least some warning, but not even that. Is this a
    > feature of the newest C dialect or something, that you can provide
    > arbitrary arguments to a function having no arguments?


    The signature:

    void f()

    does NOT mean 'no arguments',
    it means 'unspecified arguments'.

    If you want 'no arguments', write:

    void t(void)

    An empty parameter list means no arguments
    in That Other Language, but not in C.

    -Mike
     
    Mike Wahler, Nov 6, 2007
    #11
  12. Paul Melis

    cr88192 Guest

    "James Kuyper" <> wrote in message
    news:9sEXi.8488$h17.1715@trnddc04...
    > cr88192 wrote:
    >> "santosh" <> wrote in message
    >> news:fgn135$vud$...
    >>> On Monday 05 Nov 2007 5:32 pm Paul Melis <> wrote in
    >>> article <>:
    >>>
    >>>> Can someone explain to me why the following code compiles without
    >>>> errors on gcc 4.0.2?
    >>>>
    >>>> void f()
    >>>> {
    >>>> }
    >>>>
    >>>> void t()
    >>>> {
    >>>> f(1,2,3);
    >>>> f("1");
    >>>> }
    >>>>
    >>>> I would expect at least some warning, but not even that. Is this a
    >>>> feature of the newest C dialect or something, that you can provide
    >>>> arbitrary arguments to a function having no arguments?
    >>> It's a feature of "K&R" C, i.e., a pre-Standard dialect of C. For
    >>> backwards compatibility it is still legal though not recommended.
    >>>
    >>> An empty parameter list in a function declaration tells the compiler
    >>> that the function takes an unspecified number and type of arguments and
    >>> turns of parameter cross-checking of invocations against the
    >>> declaration.
    >>>

    >>
    >> I guess a lot depends on if the compiler will still accept K&R style code
    >> (mine will not, nor will it accept some aspects of C90 syntax, such as
    >> 'implicit int', being tolerant of missing prototypes, ...).

    >
    > A conforming implementation of C99 is required to accept functions without
    > prototypes. But then, you've made it clear that conformance to any
    > particular standard is not a priority for you.
    >


    not a priority in a strict sense, but in general, compatibility is a
    worthwhile goal.

    now, in my case, I don't accept implicit int, and prototypes are generally
    required (probably 'odd' for a compiler intended for scripting, but oh
    well).

    somehow, I had thought C99 did not mandate support for these either (only,
    that compilers often retained them because they were valid in C90).


    >> of course, I am not sure whether one can view newer C dialects as infact
    >> proper supersets of the old dialects (say, C99 also implies full support
    >> of C90), or if the view is more that C in itself is actually a moving
    >> target (would seem at least implied), in truth several different
    >> languages that happen to be closly enough related that as a general rule
    >> code works between them without problem.

    >
    > C99 is almost completely backwards compatible with C90, and I don't think
    > this program is one of the exceptions to that rule (I can't be certain, I
    > don't have a copy of the C90 standard).


    C99 to C90 is not so major, and infact, they should be nearly completely
    compatible, but, C99 is very different from K&R...

    if future standards continue this pattern, and compilers eventually drop
    support for older constructions, then infact, C code from different eras can
    be viewed as, effectively, different languages.

    similar can be said about English as well, for example, do Shakespeare or
    Twain use, strictly, the same language that we use now?... or is it infact
    that they are different but closely related languages, so a modern listener
    can largely understand both of these writers, but would not speak or write
    as they do, and there are cases where confusion arrises.

    this is much more emphasized if we consider Beowulf, which was, at the time,
    English...

    or, what about Cockney vs US English (various) vs Australian English ("blimy
    y'all, dose be some fatty mosies, yo...").

    yet, in general, we regard English as a singular language.


    the only other possibility would be that each is a strict superset of the
    previous, and in effect that each newer version formally included all
    previously defined constructions and semantics (rather than, most of them).

    however, as far as I have understood it, this may not be the case.

    or such...
     
    cr88192, Nov 6, 2007
    #12
  13. Paul Melis

    James Kuyper Guest

    cr88192 wrote:
    > "James Kuyper" <> wrote in message
    > news:9sEXi.8488$h17.1715@trnddc04...

    ....
    >> A conforming implementation of C99 is required to accept functions without
    >> prototypes. But then, you've made it clear that conformance to any
    >> particular standard is not a priority for you.
    >>

    >
    > not a priority in a strict sense, but in general, compatibility is a
    > worthwhile goal.
    >
    > now, in my case, I don't accept implicit int, and prototypes are generally
    > required (probably 'odd' for a compiler intended for scripting, but oh
    > well).
    >
    > somehow, I had thought C99 did not mandate support for these either (only,
    > that compilers often retained them because they were valid in C90).


    Implicit int was dropped, but otherwise support for K&R style
    declarations is still mandatory. It's hard to notice this fact unless
    you know what to look for. The relevant standardese talks about
    identifier lists and declaration lists, not "K&R" declarations.

    6.7.5.3p5 says that a function declarator may have either a parameter
    type list, or a an identifier list. 6.7.5.3p14 describes the meaning of
    such a list.

    6.9.1p1 describes the syntax of a function definition, including an
    optional declaration list between the declarator and the function body.
    6.9.1p5 says that "If the declarator includes a parameter type list, ...
    No declaration list shall follow." 6.9.1p6 describes the required
    relationship between the identifier list in a declarator, and the
    declaration list that follows it.

    > the only other possibility would be that each is a strict superset of the
    > previous, and in effect that each newer version formally included all
    > previously defined constructions and semantics (rather than, most of them).
    >
    > however, as far as I have understood it, this may not be the case.


    Correct: C99 is not a strict superset of C90, and I suspect that this is
    typical of updates to language standard.
     
    James Kuyper, Nov 6, 2007
    #13
  14. Paul Melis

    cr88192 Guest

    "James Kuyper" <> wrote in message
    news:vHZXi.4801$b%1.4530@trnddc01...
    > cr88192 wrote:
    >> "James Kuyper" <> wrote in message
    >> news:9sEXi.8488$h17.1715@trnddc04...

    > ...
    >>> A conforming implementation of C99 is required to accept functions
    >>> without prototypes. But then, you've made it clear that conformance to
    >>> any particular standard is not a priority for you.
    >>>

    >>
    >> not a priority in a strict sense, but in general, compatibility is a
    >> worthwhile goal.
    >>
    >> now, in my case, I don't accept implicit int, and prototypes are
    >> generally required (probably 'odd' for a compiler intended for scripting,
    >> but oh well).
    >>
    >> somehow, I had thought C99 did not mandate support for these either
    >> (only, that compilers often retained them because they were valid in
    >> C90).

    >
    > Implicit int was dropped, but otherwise support for K&R style declarations
    > is still mandatory. It's hard to notice this fact unless you know what to
    > look for. The relevant standardese talks about identifier lists and
    > declaration lists, not "K&R" declarations.
    >
    > 6.7.5.3p5 says that a function declarator may have either a parameter type
    > list, or a an identifier list. 6.7.5.3p14 describes the meaning of such a
    > list.
    >
    > 6.9.1p1 describes the syntax of a function definition, including an
    > optional declaration list between the declarator and the function body.
    > 6.9.1p5 says that "If the declarator includes a parameter type list, ...
    > No declaration list shall follow." 6.9.1p6 describes the required
    > relationship between the identifier list in a declarator, and the
    > declaration list that follows it.
    >


    yes, ok, good to know.

    of course, this means I am theoretically obligated to support K&R style
    function declarations, which at this point I do not (and am not particularly
    compelled by this idea...).


    >> the only other possibility would be that each is a strict superset of the
    >> previous, and in effect that each newer version formally included all
    >> previously defined constructions and semantics (rather than, most of
    >> them).
    >>
    >> however, as far as I have understood it, this may not be the case.

    >
    > Correct: C99 is not a strict superset of C90, and I suspect that this is
    > typical of updates to language standard.


    understood.


    well, in any case, I have both a subset and a superset of both...
    still C IMO, but not by strict definitions.

    it works...
     
    cr88192, Nov 7, 2007
    #14
    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. Mr. SweatyFinger
    Replies:
    2
    Views:
    2,003
    Smokey Grindel
    Dec 2, 2006
  2. grocery_stocker
    Replies:
    10
    Views:
    632
    Keith Thompson
    May 25, 2005
  3. Nagaraj
    Replies:
    1
    Views:
    876
    Lionel B
    Mar 1, 2007
  4. Replies:
    5
    Views:
    330
    Alf P. Steinbach
    Jan 25, 2009
  5. Replies:
    5
    Views:
    105
Loading...

Share This Page