tags:

views:

305

answers:

8
+4  Q: 

Two main functions

Can we have two main() functions in a C++ program?

+1  A: 

In one single program, only one entry point is allowed.

sza
+10  A: 

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.

Alex Martelli
Actually there can usually be several function with the same name, as long as they differ in their parameter...
sth
@James: Yes, I was more referring to the "just as for any other name". The global function `main` is the exception, that's why I said that a function *usually* can be overloaded. For all (?) other functions there can be several overloads that have the same name.
sth
+3  A: 

You can't overload main() in the global scope.

Brian R. Bondy
+10  A: 

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.

Prasoon Saurav
+2  A: 

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.

Jeremy Friesner
A: 

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.

Mike DeSimone
Undefined behaviour can include the behaviour that you observe. That doesn't mean "you can have more than one" and "the one in your sources wins", it just means that your implementation chose that behaviour for you. Too bad for you, just wait til your customers get less happy results.
Windows programmer
This only works if the first `main` is declared to be a weak symbol. If you have a weak symbol and a regular symbol, the regular one wins and the weak one is discarded. If you have two weak symbols, one of them wins in some fashion. If you have two regular symbols, it is an error.
Adam Rosenfield
@Windows: We've been doing this for 12 years now without problems, since gcc 2.7.2.2. But then, we target Linux, so maybe it's a Windows-vs-everything else thing. @Adam: Then it sounds like our library symbols default to being weak, assuming you're talking about Unix.
Mike DeSimone
Undefined behaviour is undefined behaviour. It doesn't matter which OS fights with which, it matters which language standard fights with Mike DeSimone.
Windows programmer
Actually, I was under the impression that it only matters if the compiler says it matters. So I'll feel free to do this until I can't. "Undefined" doesn't mean "do not do this" or "this will break"; it just means "this standard is not the relevant authority; find another".
Mike DeSimone
+14  A: 

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.

sth
+1 for quoting the standard
Adam Rosenfield
A: 

ther is only one entry point in the global scope.

MingLee