45

I read that the C++ standard forbids recursion in main(), but g++ compiles the following code without complaint:

int main()
{
    main();
}

Can anyone clarify this?

Andreas Bonini
  • 44,018
  • 30
  • 122
  • 156
  • 152
    See: http://stackoverflow.com/questions/4518598/is-it-legal-to-recurse-in-main-in-c – Paul R Dec 23 '10 at 12:26
  • 5
    @problemofficer If something compiles, it doesn't mean it is legal. It might be undefined, and then anything can happen. – BЈовић Dec 23 '10 at 12:47
  • 2
    @problemofficer: @VJo's comment was in reply to a comment by marcog that he/she has now removed. (The comment was "If it compiles, it must be legal, no?" or along those lines.) – T.J. Crowder Dec 23 '10 at 13:01
  • 3
    The question should read "Is it legal to recurse **into** main() in C++?" – Ondra Žižka Dec 23 '10 at 16:53
  • @Ondra Žižka: If you recurse in main(), what else can you be recursing into? – TonyK Dec 23 '10 at 21:44
  • 3
    @TonyK: `void f() { f(); } int main() { f(); }` Are you recursing *in* `main()`? Some people will say "No", some will say "Yes". Are you recursing *into* `main()`? No-one will say "Yes". So the latter is clearer. – j_random_hacker Jan 04 '11 at 13:27
  • @Paul I think you made a mistake. That link goes to the same page as the page it goes to. – Mateen Ulhaq Jul 14 '11 at 22:46
  • Interestingly, if you do try this with `g++`, then run the resulting program in gdb and step through the program using `next`, the stack frame always remains at 0. – Chris Gregg Aug 21 '15 at 19:00

5 Answers5

49

According to the standard in 3.6.1/3, it's not :

The function main shall not be used (3.2) within a program

The definition of used being :

An object or non-overloaded function is used if its name appears in a potentially-evaluated expression.

icecrime
  • 74,451
  • 13
  • 99
  • 111
  • 2
    This is, of course, something that is not often enforced precisely because it is only useful when you're doing programming that isn't very nice anyway. – Donal Fellows Dec 23 '10 at 12:15
  • 6
    No it does require a diagnostic. See 1.4/1 and 1.4/2. GCC is bloody wrong, and sometimes it's [more pedantic than allowed](http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41431). – Johannes Schaub - litb Dec 23 '10 at 12:46
  • @Johannes: removed the part stating that gcc what possibly allowed to compile it, thanks for the correction – icecrime Dec 23 '10 at 13:30
37

I'll do the fish and explain why this is verboten. Before a C or C++ program can start running, the CRT has to be initialized first. Open stdin/out/err, call initializers, that sort of thing. There are two basic strategies to get this done, a heavy platform implementation detail.

  • The program's start address points to the CRT init function, which eventually calls main(). Common on full-featured operating systems that have a fancy loader which can support arbitrary sections in the executable image.

  • The compiler injects code into the main() function that calls the CRT initialization function. The start function is always main(). Common on embedded platforms with limited loader capabilities. Recursing main() is now a problem, the CRT startup code will be called again with an unpredictable stack state.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • Do you have a reference for that? I can't see any reason whatsoever for injection *into* `main` rather than injection *prior* to `main`. The compiler is generating the machine code regardless, no reason for it to do so after the address it uses as the `main` symbol's value, regardless of whether the executable format allows arbitrary start addresses. – T.J. Crowder Dec 23 '10 at 15:33
  • @T.J. pretty hard to provide authoritative links to implementation details. But this question demonstrates it rather well: http://stackoverflow.com/questions/4355610/differences-in-dis-assembled-c-code-of-gcc-and-borland – Hans Passant Dec 23 '10 at 15:44
  • @Hans: Thanks. Well, if it's standard practice and it's in an open source compiler like gcc, I'd expect it to have been written up *somewhere* vaguely authoritative. I'm just seeing no good reason for this, and certainly nothing like a good enough reason to inject implementation limitations into the C++ spec. I mean, clearly they had a reason, they're not dumb, I just want to know what it is, because I find the start address argument unconvincing. – T.J. Crowder Dec 23 '10 at 16:02
  • @T.J. If you really want to know, look into [Initialization](http://gcc.gnu.org/onlinedocs/gccint/Initialization.html#Initialization). – Johannes Schaub - litb Dec 23 '10 at 16:39
  • 1
    @Johannes: Thanks. That does indeed say that depending on system architecture, that's what gcc may do. It doesn't say *why* (and I continue to find it incomprehensibly backward), but for the purposes of the OP's question and this answer, the fact it does (and that this is accepted practice) is all that's needed. Thanks again. – T.J. Crowder Dec 23 '10 at 16:45
  • @T.J. I'd guess because the thing that generates the initialization code wants to produce an entry point that something which knows nothing about initialization can link against. Hence, that entry point is `main`, and not `something_implementation_specific_that_will_init_and_then_call_main`. – Steve Jessop Dec 23 '10 at 17:26
  • @Steve: We probably shouldn't get into a discussion about this here, but nothing should need to *link to* that initialization code, at least not in that way. But again, presumably there's a good reason. – T.J. Crowder Dec 23 '10 at 18:00
22

The claim here is that it is indeed specifically forbidden:

Well, the standard states:

3.6.1.3
"The function main shall not be used within a program."

5.2.2.9
"Recursive calls are permitted, except to the function named main"

You can, of course, do this:

int main(int argc, char* argv[]) {
    return foo(argc, argv);
}
int foo(int argc, char* argv[]) {
    if (some_condition) {
        return foo(argc, argv);
    }
    return 0;
}

(Note I added a get-out clause. I can't even hypothetically code infinite recursion, it repeats on me.)

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
9

It is not legal. Read 3.6.1-3 :

The function main shall not be used (3.2) within a program. The linkage (3.5) of main is implementation-defined. A program that declares main to be inline or static is ill-formed. The name main is not otherwise reserved. [Example: member functions, classes, and enumerations can be called main, as can entities in other namespaces. ]

BЈовић
  • 62,405
  • 41
  • 173
  • 273
1

Other people have addressed the standards part. However, I'd like to note that g++ (at least 4.6.2) will reject this if you use -pedantic-errors with at least one of these errors (depending on main signature):

error: ISO C++ forbids calling ‘::main’ from within program [-pedantic]
error: ISO C++ forbids taking address of function ‘::main’ [-pedantic]
Matthew Flaschen
  • 278,309
  • 50
  • 514
  • 539