Search code examples
c++program-entry-pointinfinite-recursion

Can main function call itself in C++?


Can anybody tell what's the problem of the code below?

int main () { 
    return main(); 
}

I tested, it compiles correctly. It's running forever. Anymore trick behind the scene?


Solution

  • TLDR: Calling main results in undefined behavior, and an attempt may fail to compile, but doesn't have to.


    There seems to be confusion about the terminology used in the standard, and the implications that has for the programmer and compiler.

    Firstly, the standard alone determines everything about the C++ language. If your particular version of a particular compiler allows some particular action, that has no bearing on whether or not that action is legal. For the remainder of the post, I'm referring to the latest working draft of the standard.

    Since CWG Issue 2811 (which applies as a defect report to all versions), the C++ standard states the following in [basic.start.main] p3:

    The function main shall not be named by an expression.

    To call main, a call expression would inevitably need to name it, or you would have to take its address, which also names it. You cannot even have the potential of calling main. The compiler also shouldn't insert calls to main for no reason. This means that once the program begins executing, main should never be entered again.

    The only call to main should be by the run-time library the program is running on; all other calls should fail to compile, or are undefined behavior. (Which means anything could happen!)


    Now onto compiler behavior:

    A diagnosable rule is defined as ([intro.compliance.general]):

    The set of diagnosable rules consists of all syntactic and semantic rules in this document except for those rules containing an explicit notation that “no diagnostic is required” or which are described as resulting in “undefined behavior”.

    In our case, [basic.start.main] p3 defines a diagnosable rule. Here's what compilers should do according to [intro.compliance.general] p2:

    [...] Otherwise, if a program contains

    • a violation of any diagnosable rule,
    • a preprocessing translation unit with a #warning preprocessing directive ([cpp.error]), or
    • an occurrence of a construct described in this document as “conditionally-supported” when the implementation does not support that construct,

    a conforming implementation shall issue at least one diagnostic message.

    So compilers are not required to enforce rules. All compilers have to do is take well-formed programs and turn them into an executable program. A compiler is free to warn, error, etc. however it likes, as long as it does not conflict with the language. It is required to display a message in our particular case.

    For this particular problem, on gcc the -pedantic option will warn about the illegality of calling main within the program. Visual Studio will not warn about calling main, but on any warning level (greater than 0) it will warn about the recursive nature of the program.


    What does all this mean in terms of the answers you should expect? It means it's completely meaningless to try and define with certainty what the code snippet posted will do. Calling main results in undefined behavior, and trying to define undefined behavior is obviously a lost cause. The only honest answer anyone can give to "what happens when I call main?" is "Anything."