Just wondering why this
int main(void){}
compiles and links
and so does this:
int main(int argc, char **argv){}
Why isn't it required to be one or the other?
gcc will even compile and link with one argument:
int main(int argc){}
but issue this warning with -Wall:
smallest_1.5.c:3:1: warning: ‘main’ takes only zero or two arguments [-Wmain]
I am not asking this as in "how come they allow this?" but as in "how does the caller and the linker handle multiple possibilities for main?"
If a function takes no parameters, the parameters may be left empty. The compiler will not perform any type checking on function calls in this case. A better approach is to include the keyword "void" within the parentheses, to explicitly state that the function takes no parameters.
Yes, we can give arguments in the main() function. Command line arguments in C are specified after the name of the program in the system's command line, and these argument values are passed on to your program during program execution.
In C, the "main" function is treated the same as every function, it has a return type (and in some cases accepts inputs via parameters). The only difference is that the main function is "called" by the operating system when the user runs the program.
Creating a function is very easy. Some functions have already been made, such a function is called the built-in functions. You can also use the built-in function without having to pass parameters. The function without arguments means that you do not pass any arguments in the function.
I am taking a Linux point of view below.
The main
function is very special in the standard definition (for hosted C11 implementations). It is also explicitly known by recent compilers (both GCC & Clang/LLVM....) which have specific code to handle main
(and to give you this warning). BTW, GCC (with help from GNU libc headers thru function attributes) has also special code for printf
. And you could add your own customization to GCC using MELT for your own function attributes.
For the linker, main
is often a usual symbol, but it is called from crt0 (compile your code using gcc -v
to understand what that really means). BTW, the ld(1) linker (and ELF files, e.g. executables or object files) has no notion of types or function signatures and deals only with names (This is why C++ compilers do some name mangling).
And the ABI and the calling conventions are so defined that passing unused arguments to a function (like main
or even open(2)...) does not do any harm (several arguments get passed in registers). Read the x86-64 System V ABI for details.
See also the references in this answer.
At last, you really should practically define your main
as int main(int argc, char**argv)
and nothing else, and you hopefully should handle program arguments thru them (at least --help
& --version
as mandated by GNU coding standards). On Linux, I hate programs (and I curse their programmers) not doing that (so please handle --help
& --version
).
Because the calling code can, for example, pass arguments in registers or on the stack. The two argument main uses them, while the zero argument main does nothing with them. It's that simple. Linking does not even enter the picture.
If you are worried about stack adjustments in the called code, the main
function just needs to make sure the stack pointer is the same when it returns (and often even this is of no importance, e.g. when the ABI states that the caller is responsible for stack management).
The short answer: if you don't use the parameters, then you can declare main without parameters, in two ways:
int main(void)
or
int main()
The first means main
is a function with no parameters. The second means main
is a function with any number of parameters.
Since you don't access the parameters, both will be fine. Any compiler having "special" code to check the parameters of main
is wrong. (But: main
must return a value.)
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