Re: (part 21) Han from China answers your C questions
- From: Tim Rentsch <txr@xxxxxxxxxxxxxxxxxxx>
- Date: 19 Nov 2008 06:34:33 -0800
Keith Thompson <kst-u@xxxxxxx> writes:
Tim Rentsch <txr@xxxxxxxxxxxxxxxxxxx> writes:
Keith Thompson <kst-u@xxxxxxx> writes:[BIG SNIP]
The standard doesn't say that the definition of main must be very
similar to "int main(void) { /* ... */ }", differing only in ways that
have no effect on the particular program being considered. It says
that it must be *equivalent* (or it must follow one of the other two
options).
In practice, most or all C compilers do support "int main()" with the
obvious semantics. If my interpretation is correct (and no, I'm not
100% certain of that), then "int main()", in an implementation that
doesn't document it, invokes undefined behavior; [...]
A good argument, and well presented.
Thank you.
The argument hinges on the function definition
int main(){ return 0; }
not supplying a prototype for main(). Is that in fact the case? I
would like to give an argument that this definition does in fact
supply a prototype for main(). First the definition for prototype,
given in the last sentence of 6.2.1p2:
For each different entity that an identifier designates, the
identifier is visible (i.e., can be used) only within a region of
program text called its scope. Different entities designated by the
same identifier either have different scopes, or are in different
name spaces. There are four kinds of scopes: function, file, block,
and function prototype. (A function prototype is a declaration of a
function that declares the types of its parameters.)
Now a relevant paragraph from the section on function declarators,
namely 6.7.3p14:
Typo: that's 6.7.5.3p14.
Quite right, thank you for the correction.
An identifier list declares only the identifiers of the parameters of
the function. An empty list in a function declarator that is part of
a definition of that function specifies that the function has no
parameters. The empty list in a function declarator that is not part
of a definition of that function specifies that no information about
the number or types of the parameters is supplied.(126)
Note the second sentence, and contrast it with the third sentence.
Also, this paragraph being in the section on function /declarators/
is germane to the argument. The explicit specification that the
declared function has no parameters means this declaration does
indeed declare the types of its parameters.
Fascinating. I've always assumed that an empty list was just the
zero-parameter case of a K&R-style non-prototype declaration, but the
above implies that it acts like a "(void)" prototype.
Syntactically, it does in fact match the K&R-style syntax rule,
and not the parameter-type-list syntax rule. My argument is
that, whichever syntax rule is involved, an empty parameter list
in a function definition satisfies the definition of "prototype"
and therefore ought to be considered as such.
I still suspect that that wasn't the intent. I think what was meant
is that the "()" specifies *for the function definition* that the
function has no parameters. And just as a matter of consistency, I'd
prefer to have a general (implied) rule that any function declaration
that was legal in K&R1 is not a prototype.
Yes, the DR makes clear that it wasn't the intent. Your point about
the function having no parameters brings out a subtle distinction. If
we consider (giving the right section number this time!) 6.7.5.3p5:
If, in the declaration ..T D1.., D1 has the form
D( parameter-type-list )
or
D( identifier-listopt )
and the type specified for ident in the declaration ``T D'' is
``derived-declarator-type-list T'', then the type specified for
ident is ``derived-declarator-type-list function returning T''.
In p14 it's the /function/ that has no parameters, whereas in p5
it's the /type specified for ident/ that has a particular return
type. This distinction, which I hadn't noticed before, weakens
my argument.
But of course we have to go by what the standard actually says.
If your interpretation is correct, then the call to main in this:
int main() { return 0; }
void foo(void) { main(42); }
violates a constraint; I haven't seen a compiler that will diagnose
it.
[remainder snipped]
Yes, that's a valid conclusion, and it isn't surprising that
compilers don't report it. This gives a slim ray of hope --
if compilers simply started reporting this as an error
(which certainly seems reasonable, since it is guaranteed
UB if ever executed), then the standard committee might be
convinced to let such function definitions serve as prototypes.
.
- Follow-Ups:
- Re: (part 21) Han from China answers your C questions
- From: lawrence . jones
- Re: (part 21) Han from China answers your C questions
- References:
- Re: (part 21) Han from China answers your C questions
- From: Lew Pitcher
- Re: (part 21) Han from China answers your C questions
- From: Andrey Tarasevich
- Re: (part 21) Han from China answers your C questions
- From: s0suk3
- Re: (part 21) Han from China answers your C questions
- From: Ralf Damaschke
- Re: (part 21) Han from China answers your C questions
- From: Richard Heathfield
- Re: (part 21) Han from China answers your C questions
- From: Keith Thompson
- Re: (part 21) Han from China answers your C questions
- From: Richard Heathfield
- Re: (part 21) Han from China answers your C questions
- From: Harald van Dijk
- Re: (part 21) Han from China answers your C questions
- From: Richard Heathfield
- Re: (part 21) Han from China answers your C questions
- From: Keith Thompson
- Re: (part 21) Han from China answers your C questions
- From: Tim Rentsch
- Re: (part 21) Han from China answers your C questions
- From: Keith Thompson
- Re: (part 21) Han from China answers your C questions
- Prev by Date: Re: Error handling in C
- Next by Date: Re: [OT] text,data and bss
- Previous by thread: Re: (part 21) Han from China answers your C questions
- Next by thread: Re: (part 21) Han from China answers your C questions
- Index(es):
Relevant Pages
|