0

How does the main() function handle a variable number of arguments without the use of ellipses (...)? For processing variable number of arguments, last argument to the function should be ... which is not the case with the main() function.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • It gets a pointer to an array of char*... – ZivS Dec 21 '14 at 07:57
  • 3
    Simply google the signature for `main` i.e. there is lots of question on this site for this question for starters – Ed Heal Dec 21 '14 at 07:57
  • refer [this](http://stackoverflow.com/questions/3024197/what-does-int-argc-char-argv-mean) – justmscs Dec 21 '14 at 07:57
  • 1
    It doesn't cause an issue if the calling code supplies more parameters than the called function expects, if the calling code is responsible for restoring the stack after return based on number of parameters passed. The unused parameters are just ignored. – rcgldr Dec 21 '14 at 08:27

4 Answers4

4

Basically, main() is special, and it has two standard-defined forms:

int main(int argc, char **argv)
int main(void)

The system may support other forms; it is common that the environment is also made available:

int main(int argc, char **argv, char **envp)

These forms are fixed. The only unusual thing is that a system must support either of the first two (and some systems support others as well).

The variable number of command line arguments is handled via an array of pointers to strings (that's argv above), unlike say execl() from POSIX.

See also:


rahul manglani commented:

The two links you mentioned made it pretty clear. There are different possible approaches listed there, which of them is actually being used is not mentioned.

In a sense, it doesn't matter; the system simply has to work, and the people who produce 'the system' must make it work. You as the programmer using the system don't need to know how it works; you can simply assume that it does work.

Behind the scenes, what usually happens is that the 'start' function which calls main() does some fixup work (in the case of a C++ program in particular, a lot of fixup work — such as ensuring all the constructors that must be executed before main() starts are in fact executed), but ends with a fixed sequence such as:

exit(main(argc, argv, environ));

Note that environ is a global variable, extern char **environ; (which is unique among the global variables defined by POSIX in that no header declares it) and it contains the pointers to the environment variables. The 'start' code has to ensure that is set; it is trivial to pass environ as an argument to main(), therefore.

This calls main() with a fixed argument list and calls exit() if/when it returns. Indeed, Apple takes it a step further and passes a fourth argument to main(). If the called function was defined as int main(void) { … }, it simply ignores the arguments it was passed; if it was defined as int main(int argc, char **argv) { … }, it can access the command line arguments as usual; if it was defined as int main(int argc, char **argv, char **envp) { … }, then it can access the environment too.

Generally, the systems are set up so that extra arguments don't cause damage. This is a reason why C is unusual in its calling conventions and it's why the called function doesn't clean up the arguments pushed onto the stack — the called function doesn't know how many arguments were actually pushed onto the stack. It assumes that the ones it expects were provided and uses those without problems, but the calling code knows what it pushed so it can clean up properly. The biggest problems occur if the called function expects N arguments but the caller passes M arguments and M < N. (There are also issues of types pushed and the sizes of those types, etc, but that's a second-order problem.)

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • Thanks Jonathan. The two links you mentioned made it pretty clear. There are different possible approaches listed there, which of them is actually being used is not mentioned. – rahul manglani Dec 21 '14 at 09:00
2

In C/C++ main takes 2 parameters, typically called argc, and argv. The argv parameter is an array of argc char arrays. Command line arguments are passed to the program in argv. There are variations on this theme with the exact number of parameters, but main's signature is generally

int main(int argc, char **argv);
John Percival Hackworth
  • 11,395
  • 2
  • 29
  • 38
1

I interpreted this question to mean: how is it possible that main can take either zero arguments or two arguments?

While the details are obviously implementation-dependent, on most implementations, the default C calling convention is that the caller cleans the stack. Therefore, the code that calls main is at perfect liberty to always push two arguments onto the stack (argc and argv), whatever the declaration of main might be. If main is declared with no arguments, then main simply won't access the values of the arguments it receives. After main returns, the calling code clears the stack.

It should be pointed out that main isn't even special in this sense. Try this:

int printf();
int main() { printf("Hello, world!\n"); }

The C compiler will happily allow you to call printf even though, lacking an #include <stdio.h> directive, it has no idea how many arguments printf actually wants. Presumably, the code that calls main is conceptually something like this:

int main(int argc, char** argv); /* declare "main" */
main(argc, argv);                /* call "main" */

If the definition of main actually specifies zero parameters, this still works (although I believe it would technically be undefined behaviour if you actually did this).

In the case of C++, although the linkage of main is left unspecified by the standard, most implementations simply treat it as though it has C linkage, so the name is not mangled and everything above still applies.

Brian Bi
  • 111,498
  • 10
  • 176
  • 312
0

It handles it by accepting an array and array length set as variables argc and argv

you may find more data here:

http://crasseux.com/books/ctutorial/argc-and-argv.html

antonpuz
  • 3,256
  • 4
  • 25
  • 48