3

I just finished an image editor that is run through terminal console commands. After an image is edited, I'm trying to get the entire program (via a main() method) to run again but I'm a bit confused on how to do so. Here's the method I tried using to rerun the code.

void rerun()
{
    cout << "Would you like to alter another image? (Y/N) ";
    string answer;
    getline(cin, answer);
    while (answer != "Y" || answer != "N")

        if (answer == "N") {
            return;
        }
    if (answer == "Y") {
        main();
    }
}

This isn't giving me anything. What do I need to fix?

drescherjm
  • 10,365
  • 5
  • 44
  • 64
Caladin00
  • 356
  • 1
  • 3
  • 11
  • You'd probably have better luck using a loop inside `main`. – Kevin Jan 31 '17 at 03:37
  • C++ standard forbids calling main from your code. – Ari0nhh Jan 31 '17 at 03:37
  • 2
    Please post a [mcve]. – R Sahu Jan 31 '17 at 03:38
  • 3
    It is undefined behavior to call `main()`. Use a loop instead or move the code you have in `main()` to a function. – drescherjm Jan 31 '17 at 03:38
  • 1
    Possible duplicate of [Call main() itself in c++?](http://stackoverflow.com/questions/2532912/call-main-itself-in-c) – Ari0nhh Jan 31 '17 at 03:40
  • It's most likely that `std::getline` returns an empty string. Perhaps there was another call to read something else before that line using `std::cin >> someVariable;` syntax. – R Sahu Jan 31 '17 at 03:43
  • 2
    I just ran the code through an online c++ code formatter. I have done this a few hundred times under the c++ tag to fix badly formatted code. – drescherjm Jan 31 '17 at 03:44
  • 1
    @abelenky Not sure about that. C++ standard 3.6.1: `The function main shall not be used within a program.` Where exactly it says that calling main is an undefined behavior? – Ari0nhh Jan 31 '17 at 03:53

1 Answers1

2

The C++ standard prohibits the direct invocation of main(), like you're attempting to do:

3.6 Start and termination

...

3 - The function main shall not be used within a program.

main() can only be invoked from your environment, by your operating system. You cannot invoke it directly.

Therefore, you need to restructure the logic of your program, so that it has the effect of rerunning your entire program, when needed. For example:

int main(int argc, char **argv)
{
    int ret;

    do
    {
        ret = your_real_main(argc, argv);
    } while (ret == -1);

    return ret;
}

Whatever you have in your current main(), rename it as you_real_main() (and declare it accordingly), and if your_real_main() returns -1, it will be reexecuted, as if it was invoked again. All other return values get returned from main() itself, and carry whatever implication they do, for your C++ implementation.

Feel free to use any special return value from your_real_main(), instead of -1, for this behavior.

Of course, you are responsible for doing whatever is necessary to make this work correctly. Such as cleaning up all the resources you allocated, so by the time your_real_main() returns, everything that's been allocated has been freed, and the state of your application is identical to what it was when it was started (all dynamically-allocated memory has been released, all files have been closed, etc...).

With some careful planning, it is also possible to implement the same result by using a carefully-thrown exception, rather than a special return value. Then there may be operating system-specific means of accomplishing the same goals, such as exec() on Linux, also...

Sam Varshavchik
  • 114,536
  • 5
  • 94
  • 148