18
#include <iostream>
#include <cstdlib>

int main() {
    cout << "!!!Hello World!!!" << endl;
    system("pause");
    return main();
}

The above works, but it hardcoded the main() function. Is there a magic variable or macro to get the current running function?

S.S. Anne
  • 15,171
  • 8
  • 38
  • 76
Mask
  • 33,129
  • 48
  • 101
  • 125
  • 1
    If you want to get a function pointer or something to the current function, i don't think that's possible. – Johannes Schaub - litb Mar 28 '10 at 12:49
  • That is infinite recursion... it may compile, but "works" isn't quite right. – Michael Aaron Safyan Mar 28 '10 at 12:49
  • 1
    @Michael Actually, assuming main() is a function that can be called, the above tail recursion can be optimised by the compiler to a loop, which will "work". –  Mar 28 '10 at 12:54
  • 2
    @Neil: Can you name a C or C++ compiler that optimizes the tail call away? – JUST MY correct OPINION Mar 28 '10 at 13:20
  • 4
    @ttmrichter In this specific case no, because the call is illegal, but in the general case GCC does this. See http://stackoverflow.com/questions/2385599/visual-c-tail-call-optimization –  Mar 28 '10 at 13:26
  • Duplicate: http://stackoverflow.com/questions/2128321/can-main-function-call-itself-in-c/ – GManNickG Mar 28 '10 at 18:54
  • The C++ standard in [3.6.1](http://eel.is/c++draft/basic.start.main) [basic.start.main] says `The function main shall not be used within a program.` - it is illegal to call `main()` from `main()`, so what happens if you do is undefined behavior. – kfsone Sep 12 '16 at 02:58
  • 1
    Possible duplicate of [Can main function call itself in C++?](https://stackoverflow.com/questions/2128321/can-main-function-call-itself-in-c) – S.S. Anne Mar 25 '19 at 20:19

4 Answers4

17

Is it allowed in "C++"? No.

In practice, can you call main()? Yes.

Whatever the C++ Standard says, that doesn't stop the Linux g++ compiler from compiling code with main() in main().

#include <cstdlib>
#include <iostream>
using namespace std;
int main()
{
 int y = rand() % 10; // returns 3, then 6, then 7
 cout << "y = " << y << endl;
 return (y == 7) ? 0 : main();
}

Which lets us do:

 > g++ g.cpp; ./a.out
 y = 3
 y = 6
 y = 7

Looking in to the assembly, we see that main is called just like any other function would be:

main:
        ...
        cmpl    $7, -12(%rbp)
        je      .L7
        call    main
        ...
.L7:
        ...
        leave
        ret

Not that this behavior is guaranteed, but it looks like g++ doesn't seem to really care about the standard, apart from this sarcastic warning with -pedantic

g.cpp:8: error: ISO C++ forbids taking address of function '::main'
Carl Walsh
  • 6,100
  • 2
  • 46
  • 50
13

The C++ Standard says that you may not call main() from your own code. As for getting the name of the current function, you could use the __FUNCTION__ macro, but once again this is not standard:

#include <iostream>
using namespace std;

void foo() {
   cout << __FUNCTION__ << endl;
}

int main() {
   foo();
}

should print "foo" or something similar if __FUNCTION__ is supported.

  • @Neil, \_\_FUNCTION\_\_ is going to be string... it cannot be invoked. – Michael Aaron Safyan Mar 28 '10 at 12:50
  • @Michael I know. I wasn't clear (not for the first time) what @Mask was actually asking about. The above is about as good as you are going to get as regards function metadata. –  Mar 28 '10 at 12:52
  • 2
    Well, if you're going to assume non-standard `__FUNCTION__`, then you could also assume non-standard `dlopen` and `dlsym` (or equivalent), and get a function pointer that way... – Steve Jessop Mar 28 '10 at 12:54
9

If a specific implementation allows this, it is not behaving correctly(a). The standard state quite explicitly in C++14, 3.6.1 Main function /3:

The function main shall not be used within a program.


(a) Keep in mind that many implementations follow some parts of the standard loosely, preferring power over strictness. That can have the unfortunate side effect that your code may not be portable to other compilers or even other versions of the same compiler.

Many implementations will also allow you to take the stricter view, such as using g++ -std=c++11 -Werror=pedantic which catches the particular issue bought up in this question, as well as quite a few others. It is that "mode" of translation that allows implementations to claim to be compliant with the standard, as per 1.4 Implementation compliance:

If a program contains a violation of any diagnosable rule ..., a conforming implementation shall issue at least one diagnostic message.

You'll see it's still quite possible to allow the code to compile and run in that case, since "diagnostic message" can mean a warning rather than an error.

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
0

Generally, no. For now it will be enough for you to know that the compiler needs to know the exact function you're calling at the compile time. You cannot do magic like, let's say

func = "my_function"; 
func(); 

if the called function name will change during runtime. (There are exceptions and ways around that, but you don't need that).

Don't think about that as a case of hard-coding: it is not. If you need to call the function, then you just write its name, and don't try to abstract it, or something.

Also, now would be a nice way to learn about the while loop, infinite loops and write without the function calls at all, e.g

int main()
{
    while (1) {
        cout << "!!!Hello World!!!" << endl; // prints !!!Hello World!!!
        system("pause");
    }
}
Einar Lielmanis
  • 347
  • 1
  • 4