> This is all a bit academic, but anyway: > > The difference is in "that is part of a definition" and "that is > not part of a definition". So: > > int main(); > > declares main as function but not anything about parameters (main has no > prototype then). While: > > int main() { ...; return 0; } > > declares (and defines) main to be a function having no parameters. Even > the first variant (i.e. missing prototype without parameter info) is no > license to make main (or any other function) accept any number of > parameters. This is because "any number of params" would be a stdarg > function, which must be declared and defined with a parameter type list > that includes an ellipsis at the end. You could call such function with > arbitrary number and types of arguments, and the compiler wouldn't reject > this, but at runtime it won't work. The prototype is what is checked, so > without one no checks are done. But even without prototype the calls need > to match the implementation of the function at run time (otherwise: > undefined behaviour). > > Additionally the "or in some other implementation-defined manner" gives us > leeway to accept more declarations than strictly required, which makes us > okay to accept: > > void main(void); > > (i.e. without return type). That is good, because in the wild this usage > of main() happens, so we better accept it as well. > > > Was this implemented intentionally or just happened? > > I'm not sure what "this" refers to here,
I meant the TCC tests here; my apologies for not making it clearer in the first place. > but we basically need to accept > any of these forms of decls and defs of main: > > int main(); > int main() { ... } > void main(); > void main() { ... } > int main(int argc, char *argv[]); > int main(int argc, char *argv[]) { ... } > void main(int argc, char *argv[]); > void main(int argc, char *argv[]) { ... } > > We need to accept these in such way that the user has to be able to > write a prototype for main, and has to be able to _not_ have to write a > prototype for it before definition. If he chooses to write a prototype it > must be compatible with the given definition as usual. > We need not accept other forms of main. E.g. GCC warns > with other forms, but TCC does not. Sometimes it's convenient (when you > know something about the C libraries implementation) to define main like > so: > > int main(int argc, char *argv[], char *envp[]) { ... } > > or even add another one (auxv) on some libc's, so adding more checks for > validity would have to be done carefully to not disallow valid uses in the > wild. > > The reason why main() is so special-cased in the standard is historic. > > I'm not sure if the above answers your question(s), if not, try asking > more ;-) > For the moment I think you gave me enough information to grasp. Thank you very much. > > Ciao, > Michael. _______________________________________________ Tinycc-devel mailing list Tinycc-devel@nongnu.org https://lists.nongnu.org/mailman/listinfo/tinycc-devel