Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 8 years ago.
Improve this question
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.
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:
How does the main() function in C work?
What should main() return in C and C++?
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.)
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);
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.
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
Related
Consider this simple program:
#include <iostream>
void length(void){
std::cout<<"My length is void"<<std::endl;
}
void width(void){
std::cout<<"My width is void"<<std::endl;
}
int main(void){
std::cout<<"The program length is: "<<length<<std::endl;
std::cout<<"The program width is: "<<width<<std::endl;
}
The output of this program is:
The program length is: 1
The program width is: 1
What are the numbers that the program prints out, and basically not having much knowledge in C++ particularly, this looks more pythonic syntax to me,and looks as if it should print the function address. I say this because, this problem arose initially while practicing some very basic programs for openGL,
The callback was registered in GLUT with something like:
void line(void){
//some code for line program ...
}
int main(int argc, char** argv){
//some more code;
glutDisplayFunc(line);
glutMainLoop();
}
It's almost seeming as if we're passing the address of the function, but, clearly from the above program this is not an address, and the syntax for pointer to function is a bit different, if so, how is this function being registered for callback? And what is it that we're passing to glutDisplayFunc?
and, since I **wanted to register a function that had passed arguments, I search a C++ analogy for python lambda functions, and found similar lambda function, but it didn't work out: **
#include <iostream>
void line(int a, int b){
//some code that does some plotting in the display window
}
int main(int argc, char** argv){
auto callback = [](void)->void{
line(a,b);
};
glutDisplayFunc(callback);
glutMainLoop();
}
This totally fails,the error that is shown is:
no suitable conversion function from "lambda []void ()->void" to "void (*)()" exists
This was using my python analogy, but what's the solution to this problem? The major parts of confusion are highlighted in bold.
It's almost seeming as if we're passing the address of the function, but, clearly from the above program this is not an address
You've got things backwards. It's not glutDisplayFunc that's doing the weird magical thing; it's std::cout.
Yes, a function name will convert to a function pointer. The combination of operator<< overloads for iostreams and C++ overload resolution rules ultimately leads to << treating functions as if they were boolean values (yes, really). And thus, your << length is equivalent to doing << true.
If you want the address, you can cast the function pointer to a void* before outputting it: << reinterpret_cast<void*>(&length) or the more terse << (void*)&length (though technically this is only conditionally supported by C++, pretty much every real compiler will allow this).
Lastly, in C++, lambdas are not functions; they're objects. You cannot pass an object to something that expects a function pointer. You can convert a capture-less lambda into a function pointer, but you can't do that for one which captures values.
I've recently started learning C++ and I'm a bit confused about argv and argc. I am trying to determine if arguments were passed to a program by checking the size of argc, but no matter how many arguments (including none) I pass to the program the size of it is always 4.
Simple example:
int main(int argc, char** argv)
{
std::cout << sizeof(argc); //outputs 4 with 0 or any num of arguments
std::cout << sizeof(argv); //outputs 8 with 0 or any num of arguments
}
I found this same question asked before and I apologise for repeating it but the answers on those pages I found were contradictory to what's happening here.
So, why is argc always 4 and is there any other way to check if arguments were passed to main()?
If it's relevant I'm using g++ to compile.
sizeof(argc) will always be the same value. sizeof(variable_name) gives you the size that variable takes up in memory. If you want to know how many parameters were passed you need to evaluate what the variable contains. For instance
std::cout << argc - 1;
Will have it display how may parameters were passed. The - 1 is needed because the first parameter is the name of the program so we don't want count that in the parameter count.
I am trying to determine if arguments were passed to a program by checking the size of argc
argc is the number of arguments. The size of argc is the size of int object.
So, why is argc always 4
Because the size of int object is always 4 bytes on your system.
is there any other way to check if arguments were passed to main()?
You can check the value rather than the size of argc:
std::cout << argc;
Note that there is (typically) at least one argument to the program: The command that was used to execute it.
sizeof gives you, at compile time, the size of the enclosed type.
So sizeof(argc) is sizeof(int), and sizeof(argc) is sizeof(char**). I hope you appreciate this is therefore completely independent of the arguments passed!
Simply rely on what C++ gives you: argc is the number of arguments passed, including the program name. And the number of elements in argv is the same as argc, with an addional one which is set to nullptr.
This question already has answers here:
What is the proper declaration of main in C++?
(5 answers)
Closed 9 years ago.
So in my professor's slides he simply gives examples like:
main()
{...
}
Right? But when I put this in visual studio it gives an error and it works when I put int in front of main.
Why would my professor not put int in front of main?
Can main be any other type of variable?
Also I see a lot of int main(void). Why is this necessary? Can anything else be put in as a parameter?
main returns int. In older versions of C you could leave out the int and the compiler would pretend that you had said int. In C++, if 'main' doesn't explicitly return a value, it magically returns 0. You can return three values from main: 0, EXIT_SUCCESS, and EXIT_FAILURE. 0 is equivalent to EXIT_SUCCESS. The two named values are defined in <stdlib.h> and if you're coding in C++ in <cstdlib>.
The void is a C-style declaration that a function takes no arguments. In C++ you don't need it; a function that has no arguments in its declaration takes no arguments.
In general, though, main takes two arguments:
int main(int argc, char *argv[])
Those are the command-line arguments. argc is the number of arguments, and argv is an array of pointers to C-style strings that hold the arguments. The first string (argv[0]) is the name of the program.
Because you are using either: C++ or C99 or C11.
C89 had an implicit int rule that mades main() equivalent to int main(). This does not exist in C++ and no longer exists since C99.
As you mentioned you are using Visual Studio and it does not support C99 and C11, you are probably compiling your program with the C++ compiler and not the C compiler.
The standard form of the main function, traditionally, is
int main(int argc, char **argv)
The int in the front means the main function returns an int, which is the exit code of main. The perimeter passed in by the operating system argc and argv are related to command-line arguments. argc is an int indicating the number of arguments passed in to the program, including the name of the program. And argv is pointed to the individual arguments. You can use argv[index] to access them. There are several handy libraries for parsing arguments, such as getopt.
Should I use exit() or just return statements in main()? Personally I favor the return statements because I feel it's like reading any other function and the flow control when I'm reading the code is smooth (in my opinion). And even if I want to refactor the main() function, having return seems like a better choice than exit().
Does exit() do anything special that return doesn't?
Actually, there is a difference, but it's subtle. It has more implications for C++, but the differences are important.
When I call return in main(), destructors will be called for my locally scoped objects. If I call exit(), no destructor will be called for my locally scoped objects! Re-read that. exit() does not return. That means that once I call it, there are "no backsies." Any objects that you've created in that function will not be destroyed. Often this has no implications, but sometimes it does, like closing files (surely you want all your data flushed to disk?).
Note that static objects will be cleaned up even if you call exit(). Finally note, that if you use abort(), no objects will be destroyed. That is, no global objects, no static objects and no local objects will have their destructors called.
Proceed with caution when favoring exit over return.
http://groups.google.com/group/gnu.gcc.help/msg/8348c50030cfd15a
Another difference:
exit is a Standard Library
function so you need to include
headers and link with the standard
library. To illustrate (in C++),
this is a valid program:
int main() { return 0; }
but to use exit you'll need an include:
#include <stdlib.h>
int main() { exit(EXIT_SUCCESS); }
Plus this adds an additional assumption: that calling exit from main has the same side effects as returning zero. As others have pointed out, this depends on what kind of executable you're building (i.e., who's calling main). Are you coding an app that uses the C-runtime? A Maya plugin? A Windows service? A driver? Each case will require research to see if exit is equivalent to return. IMHO using exit when you really mean return just makes the code more confusing. OTOH, if you really do mean exit, then by all means use it.
There is at least one reason to prefer exit: If any of your atexit handlers refer to automatic-storage-duration data in main, or if you used setvbuf or setbuf to assign to one of the standard streams an automatic-storage-duration buffer in main, then returning from main produces undefined behavior, but calling exit is valid.
Another potential usage (usually reserved for toy programs, however) is to exit from a program with recursive invocations of main.
I always use return because the standard prototype for main() says that it does return an int.
That said, some versions of the standards give main special treatment and assume that it returns 0 if there's no explicit return statement. Given the following code:
int foo() {}
int main(int argc, char *argv[]) {}
G++ only generates a warning for foo() and ignores the missing return from main:
% g++ -Wall -c foo.cc
foo.cc: In function ‘int foo()’:
foo.cc:1: warning: control reaches end of non-void function
I STRONGLY second the comment by R. about using exit() in order to avoid having automatic storage in main() reclaimed before the program actually ends. A return X; statement in main() is not precisely equivalent to a call to exit(X);, since the dynamic storage of main() vanishes when main() returns, but it it does not vanish if a call to exit() is made instead.
Furthermore, in C or any C-like language a return statement strongly hints to the reader that execution will continue in the calling function, and while this continuation of execution is usually technically true if you count the C startup routine which called your main() function, it's not exactly what you mean when you mean to end the process.
After all, if you want to end your program from within any other function except main() you must call exit(). Doing so consistently in main() as well makes your code much more readable, and it also makes it much easier for anyone to re-factor your code; i.e. code copied from main() to some other function won't misbehave because of accidental return statements that should have been exit() calls.
So, combining all of these points together the conclusion is that it's a bad habit, at least for C, to use a return statement to end the program in main().
Does exit() do anything special that 'return' doesn't?
With some compilers for uncommon platforms, exit() might translate its argument into your program's exit value while a return from main() might just pass the value directly to the host environment without any translation.
The standard requires identical behavior in these cases (specifically, it says returning something that's int-compatible from main() should be equivalent to calling exit() with that value). The problem is that different OSes have different conventions for interpreting the exit values. On many (MANY!) systems, 0 means success and anything else is a failure. But on, say, VMS, odd values mean success and even ones mean failure. If you returned 0 from main(), a VMS user would see a nasty message about an access violation. There wasn't actually an access violation--that was simply the standard message associated with failure code 0.
Then ANSI came along and blessed EXIT_SUCCESS and EXIT_FAILURE as arguments you could pass to exit(). The standard also says that exit(0) should behave identically to exit(EXIT_SUCCESS), so most implementations define EXIT_SUCCESS to 0.
The standard, therefore, puts you in a bind on VMS, as it leaves no standard way to return a failure code that happens to have the value 0.
The early-1990s era VAX/VMS C compiler therefore did not interpret the return value from main(), it simply returned whatever value to the host environment. But if you used exit() it would do what the standard required: translate EXIT_SUCCESS (or 0) into a success code and EXIT_FAILURE into a generic failure code. To use EXIT_SUCCESS, you had to pass it to exit(), you could not return it from main(). I don't know whether more modern versions of that compiler preserved that behavior.
A portable C program used to look like this:
#include <stdio.h>
#include <stdlib.h>
int main() {
printf("Hello, World!\n");
exit(EXIT_SUCCESS); /* to get good return value to OS */
/*NOTREACHED*/ /* to silence lint warning */
return 0; /* to silence compiler warning */
}
Aside: If I recall correctly, the VMS convention for exit values is more nuanced than odd/even. It actually uses something like the low three bits to encode a severity level. Generally speaking, however, the odd severity levels indicated success or miscellaneous information and the even ones indicated errors.
In C returning from main is exactly the same as calling exit with the same value.
Section 5.1.2.2.3 of the C standard states:
If the return type of the main function is a type compatible with int
, a return from the initial call to the main function is equivalent to
calling the exit function with the value returned by the main
function as its argument; 11) reaching the } that terminates the
main function returns a value of 0. If the return type is
not compatible with int , the termination status returned to the
host environment is unspecified.
The rules for C++ are a bit different as mentioned in other answers.
There actually IS a difference between exit(0) and return(0) in main – when your main function is called multiple times.
The following program
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** argv) {
if (argc == 0)
return(0);
printf("%d", main(argc - 1, argv));
}
Run as
./program 0 0 0 0
Will result in following output:
00000
However this one:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** argv) {
if (argc == 0)
exit(0);
printf("%d", main(argc - 1, argv));
}
Won't print anything regardless of the arguments.
If you are sure that nobody will ever call your main explicitly it is not technically a big difference in general, but to maintain clearer code exit would look much better. If you for some reason want to call main – you should adjust it to your needs.
Speaking about C.
This question already has answers here:
What should main() return in C and C++?
(19 answers)
Closed 9 years ago.
Does it matter which way I declare the main function in a C++ (or C) program?
The difference is one is the correct way to define main, and the other is not.
And yes, it does matter. Either
int main(int argc, char** argv)
or
int main()
are the proper definition of your main per the C++ spec.
void main(int argc, char** argv)
is not and was, IIRC, a perversity that came with older Microsoft's C++ compilers.
https://isocpp.org/wiki/faq/newbie#main-returns-int
Bjarne Stroustrup made this quite clear:
The definition void main() is not and never has been C++, nor has it even been C.
See reference.
You should use int main. Both the C and C++ standards specify that main should return a value.
For C++, only int is allowed. For C, C99 says only int is allowed. The prior standard allowed for a void return.
In short, always int.
The point is, C programs (and C++ the same) always (should?) return a success value or error code, so they should be declared that way.
A long time ago I found this page (void main(void)) which contained many reasons outside of the "the standard says it is not valid" argument. On particular operating systems/architectures it could cause the stack to become corrupted and or other nasty things to happen.
If you're going by the spec, then you should always declare main returning an int.
In reality, though, most compilers will let you get away with either one, so the real difference is if you want / need to return a value to the shell.
In C++, main() must return int. However, C99 allows main() to have a non-int return type. Here is the excerpt from the C99 standard.
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; or in some other implementation-defined manner.
Also note that gcc does compile void main() although practically, it does a return 0; on encountering a closing brace.