tinycc-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Tinycc-devel] Clarification about log message in commit 48df89e10e


From: Stefanos
Subject: Re: [Tinycc-devel] Clarification about log message in commit 48df89e10e
Date: Tue, 20 Apr 2021 01:21:50 +0300

> 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.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]