Two main functions
Can we have two main()
f开发者_JAVA技巧unctions in a C++ program?
The standard explicitly says in 3.6.1:
A program shall contain a global function called main, which is the designated start of the program. [...] This function shall not be overloaded.
So there can one only be one one main
function in the global scope in a program. Functions in other scopes that are also called main
are not affected by this, there can be any number of them.
Only one function can be named main
outside of any namespace, just as for any other name. If you have namespaces foo
and bar
(etc) you can perfectly well have functions named foo::main
, bar::main
, and so on, but they won't be treated as anything special from the system's point of view (only the function named main
outside of any namespace is treated specially, as the program's entry point). Of course, from your main
you could perfectly well call the various foo::main
, bar::main
, and so on.
Yes! Why not?
Consider the following code:
namespace ps
{
int main(){return 0;}
}
int main()
{
ps::main();
}
Its ::main()
that will be called during execution.
You can't overload main() in the global scope.
A program can only have one entry point, but of course that one main() function can call out to other functions, based on whatever logic you care to specify. So if you are looking for a way to effectively compile two or more programs into a single executable, you can do something like this:
int main(int argc, char ** argv)
{
if (argc > 0) // paranoia
{
if (strstr(argv[0], "frogger")) return frogger_main(argc, argv);
else if (strstr(argv[0], "pacman")) return pacman_main(argc, argv);
else if (strstr(argv[0], "tempest")) return tempest_main(argc, argv);
}
printf("Hmm, I'm not sure what I should run.\n");
return 10;
}
... then just rename your 'other' main() functions to frogger_main(), pacman_main(), or whatever names you care to give them, and you'll have a program that runs as Frogger if the executable name has the word 'frogger' in it, or runs as PacMan if the executable has the name 'pacman' in it, etc.
In one single program, only one entry point is allowed.
Ooh, trick question!
Short answer: "It depends."
Long answer: As others have pointed out, you can have multiple functions named main
so long as they are in different namespaces, and only the main
in the root namespace (i.e. ::main
) is used as the main program. In fact, some threading libraries' thread classes have a method named main
that the library user overrides with the code they want run in the thread.
Now, assuming you're not doing any namespace tricks, if you try to define ::main
in two different .cpp
files, the files themselves will both compile, however, the linker will abort since there are two definitions named main
; it can't tell which to link.
(A question I have for the gurus out there: in C++, do the function definitions int main() {}
and extern "C" int main() {}
generate functions with the same signature? I haven't tried it myself.)
And now for the time you can have more than one ::main
in your program's source: if one main
is in a library (.a or .so file), and another is in your source (.o) files, the one in your sources wins and the one in the library is dropped, and linking succeeds unless there's some other problem! If you didn't write a main
, the library's main
would win. This is actually done in the support libraries that ship with lex
and yacc
; they provide a barebones main
so you don't have to write one for a quick parser.
Which leads to an interesting application: providing a main
with every library. My libraries tend to be small and focused, and so I put a main.cpp
in every one with a main
that is test or utility code for the library. For example, my shared memory library has a main
that allows all the functions for managing shared memory to be called from the command line. Then I can test a variety of cases with a bash
script. Anything that links in the shared memory library gets the test code for free, or can dispose of it simply by defining their own main
.
EDIT: Just to make sure folks are clear on the concept, I'm talking about a build that looks like:
gcc -c -o bar_main.o bar_main.cpp
ar -r libbar.a bar_main.o
ranlib libbar.a
gcc -c -o foo_main.o foo_main.cpp
gcc -o foo foo_main.o -L. -lbar
In this example, the main
in foo_main.o
beats the main
in bar_main.o
. The standard doesn't define this behavior because they don't care. There's a lot of nonstandard things that people use anyway; Linux is an example with its use of C bitfields. ld
has worked this way longer than I've known how to type.
Seriously, guys, feel free to strictly adhere to standards if you need to turn out least-common-denominator code. But if you have the luxury of working on a platform that can build lex
and yacc
programs, by all means, consider taking advantage of it.
there is only one entry point in the global scope.
精彩评论