Richard Heathfield said:
Well, if you want your program to be portable, you have to return int.
Oh, please! I didn't ask about portability! Mark McIntyre made
a rather bold assertion that C99 forbids non-int main, and I asked
only about that.
Implementations are allowed to define behaviours for alternative return
types for main
So can I assume that you disagree now with Mark here?
I don't think so, C90 allowed only two forms, both returning int.
but C99 merely makes this explicit),
so you can argue that void main is implementation-defined, but ONLY for
implementations that define it!
Well, yes, that's exactly what implementation-defined means, doesn't it?
(Everything after "but" is redundant.)
In other implementations, it remains
undefined,
If it's not defined, then it's undefined, sure.
and so it's not unreasonable to argue that the C99 standard
requires programs-intended-to-be-portable to return int.
Yes, and those programs are called "strictly conforming". However
the Standard does not preclude non-portable conforming programs
(Annex J.3 is a guide how to write them).
Pick 20 articles at random from comp.lang.c's archives. I should think that
at least 6 of them will be about void main.
Mostly people bashing other people for using non-portable `void main'.
I was looking for some valid arguments why `non-int main' should be
forbidden by C99, and have found none (maybe I haven't searched enough).
The discussions I found were mostly from 2000-2002. Among them you
claiming (citing from my memory) that "the Std never did, and never
will allow `void main'"; one post from Jack Klein saying `void main'
is disallowed in C99. Two (unrelated) posts from Dan Pop explaining that
`void main' is allowed provided that the implementation documents it.
And numerous other people that seemed important and had different
opinions.
The safe thing to do is go with int main, unless your implementation
actually forbids it (eg freestanding).
My question was not about portability, and obviously concerned only
a hosted implementation.
Could you comment on my point of view below. I'm not trying to cover
all `main' issues, just things relevant to this discussion.
C90 disallowed `non-int main' (only two forms were allowed).
Implementations that accepted other forms were not conforming.
C99 allows other (non-portable) forms, provided that the implementation
documents them. For example:
float _Complex main(int n, _Bool [restrict static 10][n],
struct { float _Imaginary im; long long fam[]; } *,
...);
(Yes, that's an ellipsis - why not?)
The exit status is meaningful only when the return type is compatible
with the type `int'.
Arguments `argc' and `argv' have their meaning only when main is
defined as "int main(int argc, char **argv)". Otherwise they haven't:
int main(int argc, char **argv, char **envp)
void main(int argc, char **argv)
In neither of above cases need `argc' and `argv' have their usual
meaning and constraints.
What changed between C90 and C99 is that what was an extension in C90,
can now be allowed, ie. a compiler does not cease to be conforming
when it accepts other (documented) forms of `main'. It's not meaningful
to anyone, but implementors.
What C90 and C99 have in common is that `main' is the function that
starts the program, and returning from the first instance finishes it.