Is "int main() { }" strictly conforming?

Discussion in 'C Programming' started by Johannes Schaub (litb), Mar 11, 2011.

  1. The spec says it can be defined as

    int main(void) { /* ... */ }

    or

    int main(int argc, char *argv[]) { /* ... */ }

    or equivalent. Or in some implementation-defined manner (not strictly
    conforming anymore).

    Because "int main() { }" is not equivalent to "int main(void) { }", I take
    it that "int main() { }" is not supported for strictly conforming programs?
     
    Johannes Schaub (litb), Mar 11, 2011
    #1
    1. Advertising

  2. "Johannes Schaub (litb)" <> writes:
    > The spec says it can be defined as
    >
    > int main(void) { /* ... */ }
    >
    > or
    >
    > int main(int argc, char *argv[]) { /* ... */ }
    >
    > or equivalent. Or in some implementation-defined manner (not strictly
    > conforming anymore).
    >
    > Because "int main() { }" is not equivalent to "int main(void) { }", I take
    > it that "int main() { }" is not supported for strictly conforming programs?


    I agree.

    If the implementation documents that "int main()" is permitted,
    then a program that uses it is well-behaved, with its behavior
    defined by the implementation.

    Otherwise, such a program's behavior is undefined.

    In practice, the actual behavior for "int main()" is almost certain to
    be the same as "int main(void)".

    --
    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, Mar 11, 2011
    #2
    1. Advertising

  3. Johannes Schaub (litb)

    Guest

    In comp.std.c "Johannes Schaub (litb)" <> wrote:
    >
    > Because "int main() { }" is not equivalent to "int main(void) { }", I take
    > it that "int main() { }" is not supported for strictly conforming programs?


    They're not equivalent as declarations because one acts as a prototype and
    the other doesn't, but they are equivalent as definitions (they both
    define main as a function taking no arguments). I'm sure the committee
    indended to allow both for strictly conforming programs, but one could
    argue that the standard doesn't actually say that (and Keith Thompson
    [forgive me if I've misspelled your name, Keith] probably will, if he
    hasn't already).
    --
    Larry Jones

    I've got to start listening to those quiet, nagging doubts. -- Calvin
     
    , Mar 11, 2011
    #3
  4. Johannes Schaub writes:
    >> Because "int main() { }" is not equivalent to "int main(void) { }", I take
    >> it that "int main() { }" is not supported for strictly conforming programs?

    >


    Keith Thompson wrote:
    > In practice, the actual behavior for "int main()" is almost certain to
    > be the same as "int main(void)".


    Here's a related question, since I'm not as adept at ISO C
    as I once was...

    Given a function definition of:
    int main() { ... }
    does the standard state that this is substantially different
    from:
    int main(void) { ... }

    My point of view is that since main() receives no arguments,
    including any varargs, how can it have any calling linkage
    different than 'main(void)'?
     
    David R Tribble, Mar 11, 2011
    #4
  5. David R Tribble wrote:

    > Johannes Schaub writes:
    >>> Because "int main() { }" is not equivalent to "int main(void) { }", I
    >>> take it that "int main() { }" is not supported for strictly conforming
    >>> programs?

    >>

    >
    > Keith Thompson wrote:
    >> In practice, the actual behavior for "int main()" is almost certain to
    >> be the same as "int main(void)".

    >
    > Here's a related question, since I'm not as adept at ISO C
    > as I once was...
    >
    > Given a function definition of:
    > int main() { ... }
    > does the standard state that this is substantially different
    > from:
    > int main(void) { ... }
    >
    > My point of view is that since main() receives no arguments,
    > including any varargs, how can it have any calling linkage
    > different than 'main(void)'?


    The key here is the meaning of "substantially different". The spec requires
    no diagnostic for

    int main() {
    main("lulz");
    }

    I prefer to get errors in my code if I do a mistake, so I would consider
    this a substantial difference.
     
    Johannes Schaub (litb), Mar 11, 2011
    #5
  6. Johannes Schaub (litb)

    jacob navia Guest

    Le 11/03/11 16:29, Johannes Schaub (litb) a écrit :
    > The spec says it can be defined as
    >
    > int main(void) { /* ... */ }
    >
    > or
    >
    > int main(int argc, char *argv[]) { /* ... */ }
    >
    > or equivalent. Or in some implementation-defined manner (not strictly
    > conforming anymore).
    >
    > Because "int main() { }" is not equivalent to "int main(void) { }", I take
    > it that "int main() { }" is not supported for strictly conforming programs?


    Can't we move this discussion to comp.std.c???

    We have discussed this here a zillion times already.

    Yes, and we should not cast the result of malloc. Yes I know.
    BUT PLEEEEEEEZE....
     
    jacob navia, Mar 11, 2011
    #6
  7. Johannes Schaub (litb)

    Tim Rentsch Guest

    "Johannes Schaub (litb)" <> writes:

    > The spec says it can be defined as
    >
    > int main(void) { /* ... */ }
    >
    > or
    >
    > int main(int argc, char *argv[]) { /* ... */ }
    >
    > or equivalent. Or in some implementation-defined manner (not strictly
    > conforming anymore).
    >
    > Because "int main() { }" is not equivalent to "int main(void) { }", I take
    > it that "int main() { }" is not supported for strictly conforming programs?


    will respond in comp.std.c.
     
    Tim Rentsch, Mar 12, 2011
    #7
  8. Johannes Schaub (litb)

    James Kuyper Guest

    On 03/11/2011 11:46 PM, pete wrote:
    > David R Tribble wrote:
    >>
    >> Johannes Schaub writes:
    >>>> Because "int main() { }" is not equivalent to "int main(void) { }", I take
    >>>> it that "int main() { }" is not supported for strictly conforming programs?
    >>>

    >>
    >> Keith Thompson wrote:
    >>> In practice, the actual behavior for "int main()" is almost certain to
    >>> be the same as "int main(void)".

    >>
    >> Here's a related question, since I'm not as adept at ISO C
    >> as I once was...
    >>
    >> Given a function definition of:
    >> int main() { ... }
    >> does the standard state that this is substantially different
    >> from:
    >> int main(void) { ... }
    >>
    >> My point of view is that since main() receives no arguments,
    >> including any varargs, how can it have any calling linkage
    >> different than 'main(void)'?

    >
    > Section 6.91, footnote 137, has examples which show
    > that two function definitions like those above,
    > are compatible.
    >
    > typedef int F(void); // type F is ��function with no parameters
    > // returning int��
    >
    > int f(void) { /* ... */ } // RIGHT: f has type compatible with F
    > int g() { /* ... */ } // RIGHT: g has type compatible with F


    The key point is that the requirement specified by the standard is that
    any alternatives be "equivalent" to the specified forms, not
    "compatible" with them. Unlike "compatible", the standard provide no
    specific definition of "equivalent" that applies in this context. The
    closest it comes is footnote 9, which lists a couple of ways in which
    the declaration can be different while remaining equivalent. Those
    examples neither clearly include nor clearly exclude this case. The
    Rationale does not address this issue either.

    However, the fact that it did not use the word "compatible", even though
    the word was available and well-defined, implies that "compatible" would
    not have conveyed the intent of that passage.
    --
    James Kuyper
     
    James Kuyper, Mar 12, 2011
    #8
  9. On Mar 12, 12:22 pm, James Kuyper <> wrote:
    > However, the fact that it did not use the word "compatible", even though
    > the word was available and well-defined, implies that "compatible" would
    > not have conveyed the intent of that passage.


    enum compatible_with_int_1 { please=-1, dont, let };
    enum compatible_with_int_2 { this=-1, be, valid };

    /* whether the enums are compatible with int is implementation-
    defined. */

    int check_compatibility_1;
    enum compatible_with_int_1 check_compatibility_1;

    int check_compatibility_2;
    enum compatible_with_int_2 check_compatibility_2;

    /* if they are not, a diagnostic will be generated for the above
    lines.
    but on my system, they are compatible. */

    enum compatible_with_int_1 main(void) {
    int (*p)(void) = main;
    return 0;
    }

    This definition of main is compatible with but not equivalent to int
    main(void): unlike int main(void), it is incompatible with enum
    compatible_with_int_2 main(void). And unlike the int main() case,
    there is no possible way to argue that this is "equivalent as a
    definition only".
     
    Harald van Dijk, Mar 12, 2011
    #9
  10. Harald van Dijk <> writes:
    > On Mar 12, 12:22 pm, James Kuyper <> wrote:
    >> However, the fact that it did not use the word "compatible", even though
    >> the word was available and well-defined, implies that "compatible" would
    >> not have conveyed the intent of that passage.

    >
    > enum compatible_with_int_1 { please=-1, dont, let };
    > enum compatible_with_int_2 { this=-1, be, valid };
    >
    > /* whether the enums are compatible with int is implementation-
    > defined. */
    >
    > int check_compatibility_1;
    > enum compatible_with_int_1 check_compatibility_1;
    >
    > int check_compatibility_2;
    > enum compatible_with_int_2 check_compatibility_2;
    >
    > /* if they are not, a diagnostic will be generated for the above
    > lines.
    > but on my system, they are compatible. */
    >
    > enum compatible_with_int_1 main(void) {
    > int (*p)(void) = main;
    > return 0;
    > }
    >
    > This definition of main is compatible with but not equivalent to int
    > main(void): unlike int main(void), it is incompatible with enum
    > compatible_with_int_2 main(void). And unlike the int main() case,
    > there is no possible way to argue that this is "equivalent as a
    > definition only".


    I'd say that 5.1.2.2.1p1 doesn't permit this *unless* the
    implemetation documents it as "some other implementation-defined
    manner".

    If it is, then 5.1.2.2.3 applies; since the return type is compatible
    with int, the status returned to the host environment is defined.

    If the implementation permits "long main(void)", then 5.1.2.2.3
    doesn't apply, and the status returned to the host environment is
    undefined (unless the implementation defines it, which it certainly
    should). (Note that int and long are not compatible even if they
    happen to have the same representation.)

    --
    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, Mar 12, 2011
    #10
  11. On Sat, 12 Mar 2011 06:22:44 -0500, James Kuyper
    <> wrote:

    > On 03/11/2011 11:46 PM, pete wrote:
    > > David R Tribble wrote:

    <snip: is int main() 'equivalent' to int main(void) and thus legit?>

    > > Section 6.91, footnote 137, has examples which show
    > > that two function definitions like those above,
    > > are compatible.
    > >

    Aside: that's 6.9.1.

    > > typedef int F(void); // type F is ??function with no parameters
    > > // returning int??
    > >
    > > int f(void) { /* ... */ } // RIGHT: f has type compatible with F
    > > int g() { /* ... */ } // RIGHT: g has type compatible with F

    >

    True; but int g() is also compatible with int h(int x, double y).
    Function compatibility is much weaker for K&R1-style function
    declarations, including definitions functioning(!) as declarations.
    See 6.7.5.3p16 for details, although not much explanation.
    So 'compatible' can't be, and per below isn't, the criterion used.

    Useless aside: pete's newsreader (which identifies as Mozilla 3) used
    Microsoft's nonstandard 'smart' quotes 0x91 and 0x92 but asserted
    charset=iso-8859-1, and yours (ditto Mozilla 5) properly but
    unhelpfully munged to UTF-8 U+FFFD Replacement.
    I can't check what's actually in the Standard here, only what Adobe
    Reader gives me, and I trust that as far as I can throw it.

    > The key point is that the requirement specified by the standard is that
    > any alternatives be "equivalent" to the specified forms, not
    > "compatible" with them. Unlike "compatible", the standard provide no
    > specific definition of "equivalent" that applies in this context. The
    > closest it comes is footnote 9, which lists a couple of ways in which
    > the declaration can be different while remaining equivalent. Those
    > examples neither clearly include nor clearly exclude this case. The
    > Rationale does not address this issue either.
    >

    Yes the documents don't clearly say so, but J11 must have intended to
    allow K&R1-style for both 0-arg and 2-arg forms. As Tim Rentsch says,
    in 1999 there was still a lot of K&R1-style code, and C99 retains
    K&R1-style declaration and definition even though C89 had labelled
    them obsolescent (and C99 still does). Even further, C89 didn't have
    the wording "or equivalent (footnote 9)" yet in 1989 ALL existing code
    was K&R1, and J11's mandate, secondary only to getting a standard at
    all, was to preserve existing (K&R1) code.
     
    David Thompson, Mar 17, 2011
    #11
    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. Hal Styli
    Replies:
    14
    Views:
    1,657
    Old Wolf
    Jan 20, 2004
  2. Frederick Ding

    int main() or int main(void)?

    Frederick Ding, Dec 3, 2005, in forum: C Programming
    Replies:
    10
    Views:
    660
  3. Army1987

    int main(void) { return main(); }

    Army1987, Mar 29, 2007, in forum: C Programming
    Replies:
    37
    Views:
    1,461
    Daniel Rudy
    Apr 3, 2007
  4. Replies:
    55
    Views:
    1,482
    Lionel B
    Jan 16, 2008
  5. Tristan Wibberley

    Re: int main(void) is better than int main()

    Tristan Wibberley, Jan 4, 2008, in forum: C++
    Replies:
    1
    Views:
    346
    Lars Uffmann
    Jan 7, 2008
Loading...

Share This Page