Reputation: 2788
I started programming with following definition of main()
void main(){}
Then somebody told me that this format of main() is bad programming because it should return int. He also told me that following definitions of main() are valid in C.
int main(void){}
or
int main(int argc,int *argv[]){}
Today I tried to experiment with other data types and surprisingly all the following compiles without errors.
char main(){}
float main(){}
int* main(){}
and even this compiles successfully
struct Abc{
int a;
};
struct Abc* main(){}
So my questions regarding this are following:
How does the OS deal with these unexpected return types? [I am asking this because I think return value of main()
is used by OS]
Why is main()
allowed to return any type?
Why do compiler designers make this so flexible by saying "main()
should return int" I think there would be no problem if they said "main()
must return int"?
Upvotes: 1
Views: 695
Reputation: 6570
The OS expects return value of type int
and gets it from the default place (e.g. register EAX
). If you return other type, the OS will get value of EAX
again. Nothing special.
Upvotes: 0
Reputation: 263647
If the return type of main
is not either int
or some implementation-defined type (where "implementation-defined" means that it's documented by the implementation), the behavior is undefined.
That means that a compiler is not required to issue a warning or error message, but the C standard says nothing about how the program behaves.
The actual behavior depends on the compiler (calling conventions, etc.) and on the operating system.
In many cases, the value returned by main
(if any) will simply be interpreted as if it were an int
. If it returns a double
with the value 1.0
, it might be equivalent to returning an int
value 1065353216.
Or the compiler might reject it at compile time. Or your program might crash. As far as the C standard is concerned, literally anything can happen.
There are a lot of coding errors in C that compilers are not required to detect or to handle in any particular way. In such cases, it's entirely up to the programmer to get things right.
Just use the correct declaration. For hosted implementations, use either
int main(void) { /* ... */ }
or
int main(int argc, char *argv[]) { /* ... */ }
(For freestanding (embedded) implementations, the declaration is entirely implementation-defined, and the entry point may or may not be called main
; consult your compiler's documentation.)
As for why declaring main
incorrectly doesn't require a diagnostic, I'm not entirely sure. It does make things slightly simpler for compiler writers. They can treat main
just like any other function. There are some non-standard forms that are actually useful; for example, UNIX-like systems sometimes permit
int main(int argc, char *argv[], char *envp) { /* ... */ }
where the third argument provides access to environment variables. I personally would prefer it if incorrect definitions of main
had to be diagnosed.
This is also discussed in the comp.lang.c FAQ, starting at question 11.12a.
Upvotes: 4