Peter Nilsson said:
'some other implementation-defined manner' aside, it must
specify zero or two _parameters_. Arguments are expressions
supplied when the function is called.
6.7.5.3p14: "...An empty list in a function declarator that
is part of a definition of that function specifies that
the function has no parameters."
The more I look at this, the more bewildered I become. I think the
standard is impressively ambiguous on this (relatively minor) point.
As a practical matter of programming, there's no good reason to write
int main() { /* ... */ }
rather than
int main(void) { /* ... */ }
The latter is certainly correct; the former, if it's correct at all,
depends on the fact that the empty parentheses mean one thing in a
function definition, and something else in a prototype that's not part
of a definition.
As for what the standard says, 6.7.5.3p14 is as you say above. Here's
5.1.2.2.1p1:
The function called at program startup is named main. The
implementation declares no prototype for this function. It shall
be defined with a return type of int and with no parameters:
int main(void) { /* ... */ }
or with two parameters (referred to here as argc and argv, though
any names may be used, as they are local to the function in which
they are declared):
int main(int argc, char *argv[]) { /* ... */ }
or equivalent;9) or in some other implementation-defined manner.
Footnote 9 says:
Thus, int can be replaced by a typedef name defined as int, or the
type of argv can be written as char ** argv, and so on.
Clearly the "or equivalent" phrase is intended to allow for the
variations mentioned in the footnote.
But what is the "scope" of the "or equivalent" phrase? Does it apply
starting at "It shall be defined", or at "or with two parameters"? If
the former, then 'int main() { /* ... */ }' is legal; if not, it
isn't.
I had nearly convinced myself that the "or equivalent" applies only to
the two-parameter form, until I realized that it would mean that 'int
main' could be replaced with 'typedef_for_int main' for the
two-parameter form, but *not* for the zero-parameter form. That just
seems silly.
On the other hand, I'm not entirely convinced by an argument that
depends on *assuming* that the standard is sensible.
I think I'll raise this in comp.std.c.