Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can C main function be coded with or without parameters?

Tags:

c

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?"

like image 838
Scooter Avatar asked Sep 13 '15 13:09

Scooter


People also ask

Can a function have no parameters in C?

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.

Can main function have 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.

Can main take parameters in C?

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.

Can we define a function without the parameter?

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.


3 Answers

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

like image 134
Basile Starynkevitch Avatar answered Nov 15 '22 17:11

Basile Starynkevitch


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

like image 25
Jens Avatar answered Nov 15 '22 19:11

Jens


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

like image 21
Paul Ogilvie Avatar answered Nov 15 '22 18:11

Paul Ogilvie