The standard says:
5.1.2.2.1 Program startup
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; 10) or in some other implementation-defined manner.
If I write this:
#include <stdio.h>
struct some_struct
{
int i;
};
float main(struct some_struct s)
{
printf("Why does this main get called?\n");
}
Actually, it gets called with any prototype, as I see, and there is no any runtime error.
Why isn't it forbidden? Are there no reasons for that? Also, how does it get called if the signature is wrong?
I've used gcc (Ubuntu 4.8.2-19ubuntu1) 4.8.2
Starting with standard conformance:
1 In this International Standard, ‘‘shall’’ is to be interpreted as a requirement on an implementation or on a program; conversely, ‘‘shall not’’ is to be interpreted as a prohibition.
2 If a ‘‘shall’’ or ‘‘shall not’’ requirement that appears outside of a constraint or run time constraint is violated, the behavior is undefined. [...]
Look at the emphasis on the paragraph you quoted:
[...]. It shall be defined with a return type of int and with [...]
In the case,
float main(struct some_struct s){...}
"shall" requirement is outside of constraint because standard clearly states that main
return type shall be int
either with no parameters
int main(void) { /* ... */ }
or with two parameters
int main(int argc, char argv[]) { / ... */ }
This means that behavior of your program is undefined.
Your quote from the standard states that "some other implementation-defined manner". It appears that gcc is quite liberal in what it allows as signatures for main
; it seems to ignore the parameter that you're passing. If you compile with gcc -Wall
, you get warnings about main's prototype not being what it expects.
clang is less permissive about main's prototype. It will accept the return type of float
with a warning, but will error out on the struct argument.
C looks up functions by name only, so the linker doesn't care about the unusual return type and parameters.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With