59

I am developing a C++ program and it would be useful to use some function, script or something that makes the program restart. It's a big program so restarting all the variables manually will take me long time...

I do not know if there is any way to achieve this or if it is possible.

14
  • 40
    Whatever you do, do not call main() in your code. Commented Oct 13, 2016 at 13:38
  • 15
    "restarting all the variables manually" Wut?
    – Treycos
    Commented Oct 13, 2016 at 13:39
  • 5
    Did you consider using a loop?
    – Baum mit Augen
    Commented Oct 13, 2016 at 13:40
  • 8
    What platform? If it's anything remotely POSIX-like, you might want to look at the exec() family of functions. Commented Oct 13, 2016 at 15:42
  • 36
    This sounds like an XY problem.
    – isanae
    Commented Oct 13, 2016 at 19:36

10 Answers 10

68

If you really need to restart the whole program (i.e. to "close" and "open" again), the "proper" way would be to have a separate program with the sole purpose of restarting your main one. AFAIK a lot of applications with auto-update feature work this way. So when you need to restart your main program, you simply call the "restarter" one, and exit.

6
  • So would be enough having two programs that call each other and exit when restarting is required , wouldn't it? Commented Oct 13, 2016 at 13:48
  • 7
    They don't call each other; the caller is basically a loop that calls the second one, waits for it to exit, then calls it again. The "real" program doesn't know anything about the caller; it just exits.
    – chepner
    Commented Oct 13, 2016 at 15:29
  • 3
    And the worker may indicate via its exit code whether it wants to be restarted by the watch dog.
    – Carsten S
    Commented Oct 13, 2016 at 18:59
  • 5
    Why not just start another instance of your program, possibly specifying a flag to it that indicates that it's a restart? Commented Oct 13, 2016 at 22:27
  • Okay! Currently I execute my program automatically at boot time using a script so I can change it and make the program "restart" (execute it again) when a specific exit code arrives. Am I correct? Commented Oct 14, 2016 at 6:44
55

You can use a loop in your main function:

int main()
{
    while(!i_want_to_exit_now) {
        // code
    }
}

Or, if you want to actually restart the program, run it from a harness:

program "$@"
while [ $? -e 42 ]; do
    program "$@"
done

where 42 is a return code meaning "restart, please".

Then inside the program your restart function would look like this:

void restart() {
    std::exit(42);
}
8
  • 5
    The first solution will not work well if the program is not well-written. For example, if it contains a memory leaks, it will not get freed by simply going through a loop. However, the other solution you provided will handle even these kind of problems. Commented Oct 13, 2016 at 13:53
  • 16
    @HumamHelfawi If the program has memory leaks, they should be fixed anyhow, whether it is run in a loop or not. With the same logic you could say the first approach is not good because if the program has UB it will have UB several times... Commented Oct 13, 2016 at 13:57
  • 4
    @tobi303 No it is not good. However, the phrase "restart the program" means something like "cleaning all the garbages" or in other words: "clear everything and start fresh".. So I supposed that cleaning any leaks is part of it... Anyway, I am with you that no one leaves a leaks and use restart method to solve it. I just thought it is worth to be mentioned Commented Oct 13, 2016 at 14:01
  • 4
    This is the most specific answer. It should be marked as answer.
    – Charles
    Commented Oct 13, 2016 at 14:28
  • 4
    @HumamHelfawi: Actually, I have seen programs to analyse images that made no attempt to release memory. They were single shot programs that would be rerun externally for the next image. (I often don't worry about freeing memory in small test programs either.) Commented Oct 13, 2016 at 15:20
18

On Unicies, or anywhere else you have execve and it works like the man page specifies, you can just...kill me for using atoi, because it's generally awful, except for this sort of case.

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

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

  (void) argc;

  printf("arg: %s\n", argv[1]);
  int count = atoi(argv[1]);

  if ( getchar() == 'y' ) {

    ++count;

    char buf[20];
    sprintf(buf, "%d", count);

    char* newargv[3];
    newargv[0] = argv[0];
    newargv[1] = buf;
    newargv[2] = NULL;

    execve(argv[0], newargv, NULL);
  }

  return count;
}

Example:

$ ./res 1
arg: 1
y
arg: 2
y
arg: 3
y
arg: 4
y
arg: 5
y
arg: 6
y
arg: 7
n

7 | $

(7 was the return code).

It neither recurses nor explicitly loops -- instead, it just calls itself, replacing its own memory space with a new version of itself.

In this way, the stack will never overflow, though all previous variables will be redeclared, just like with any reinvocation -- the getchar call prevents 100% CPU utilisation.

In the case of a self-updating binary, since the entire binary (at least, on Unix-likes, I don't know about Windows) will be copied into memory at runtime, then if the file changes on disk before the execve(argv[0], ... call, the new binary found on disk, not the same old one, will be run instead.

As @CarstenS and @bishop point out in the comments, due to the unique way in which Unix was designed, open file descriptors are kept across fork/exec, and as a result in order to avoid leaking open file descriptors across calls to execve, you should either close them before execve or open them with e, FD_CLOEXEC / O_CLOEXEC in the first place -- more information can be found on Dan Walsh's blog.

8
  • 3
    What about resources that may have been acquired?
    – Carsten S
    Commented Oct 13, 2016 at 18:57
  • 1
    @CarstenS They get leaked, probably. See danwalsh.livejournal.com/53603.html
    – bishop
    Commented Oct 13, 2016 at 20:23
  • 2
    Oh, I suppose @bishop's right about open file descriptors -- those need to be closed first, or opened with FD_CLOEXEC in the first place. File descriptors are not what first come to my mind when someone talks about C/C++ leaks :)
    – cat
    Commented Oct 13, 2016 at 21:08
  • 2
    It may be instructive to strace a version of this. I wrote one that terminates: int main(int argc, char** argv) { (void)argc; printf("arg: %s\n", argv[1]); int count = atoi(argv[1]); if (count > 0) { char buf[20]; sprintf(buf, "%d", count-1); argv[1] = buf; execv(argv[0], argv); } return count; }. You can see the startup (loading libc, etc) each time around. Commented Oct 14, 2016 at 10:48
  • 1
    Don't do this in any security related context. This is vulnerable to launching any code an attacker might want to run. Commented Oct 14, 2016 at 13:42
14

This is a very OS-specific question. In Windows you can use the Application Restart API or MFC Restart Manager. In Linux you could do an exec()

However most of the time there is a better solution. You're likely better off using a loop, as suggested in other answers.

9

This sounds like the wrong approach, like all your state is global and so the only clear-cut method you have of resetting everything (other than to manually assign "default" values to each variable) is to restart the whole program.

Instead, your state should be held in objects (of class type, or whatever). You are then free to create and destroy these objects whenever you like. Each new object has a fresh state with "default" values.

Don't fight C++; use it!

6

You probably need a loop:

int main()
{
    while (true)
    {
        //.... Program....
    }
}

Every time you need to restart, call continue; within the loop, and to end your program, use break;.

5
  • 1
    Not recommended by whom? Commented Oct 13, 2016 at 17:15
  • Do you have a link? A reasoning would be nice to read. And may enhance your answer. Commented Oct 13, 2016 at 17:35
  • That's one guy, with one opinion. Asserting that these features are "not recommended" based on that one opinion is unhelpful. Personally I disagree with Peter, but his opinion is valid; it's just not the only one out there. Commented Oct 14, 2016 at 11:48
  • @LightnessRacesinOrbit Now that I think about it, I will edit out how break and continue are not recommended, because I realize how dogmatic that sounded. Thank you for pointing that out. Commented Oct 14, 2016 at 12:27
  • No problem at all. :) Commented Oct 14, 2016 at 13:04
4

When I develop realtime systems my approach is normally a "derived main()" where I write all code called from a real main(), something like:

The main.cpp program:

int main (int argc, char *argv[])
{
   while (true)
   {
       if (programMain(argc, argv) == 1)
           break;
   }
}

The programmain.cpp, where all code is written:

int programMain(int argc, char *argv[])
{
    // Do whatever - the main logic goes here

    // When you need to restart the program, call
    return 0;

    // When you need to exit the program, call
    return 1;
}

In that way, every time we decide to exit the program the program will be restarted.

Detail: all variables, globals and logic must be written inside programMain()- nothing inside "main()" except the restart control.

This approach works in both Linux and Windows systems.

3
  • Wouldn't this just loop back and call programMain again? You'd need something to break the outer while loop. I'm not a C++ guy, but I'd be surprised if a 1 return code did that, especially as you're not using it anywhere...
    – Alex
    Commented Oct 14, 2016 at 13:26
  • Yes, the idea is to call programMain() again, restarting the whole logic. Indeed the return 1 can exit the loop. Edited....
    – Mendes
    Commented Oct 14, 2016 at 14:01
  • It's clearer now. Though I would personally still prefer the approach of having a separate mini-programme to restart fully/cleanly...
    – Alex
    Commented Oct 14, 2016 at 14:30
2

It sounds to me like you're asking the wrong question because you don't know enough about coding to ask the right question.

What it sounds like you're asking for is how to write some code where, on a missed call, it loops back round to the initial state and restarts the whole call/location sequence. In which case you need to use a state machine. Look up what that is, and how to write one. This is a key software concept, and you should know it if your teachers were any good at their job.

As a side note, if your program takes 5s to initialise all your variables, it's still going to take 5s when you restart it. You can't shortcut that. So from that it should be clear that you don't actually want to kill and restart your program, because then you'll get exactly the behaviour you don't want. With a state machine you could have one initialisation state for cold startup where the system has only just been turned on, and a second initialisation state for a warm restart.

Oh, and 6 threads is not very many! :)

2
  • 1
    Of course that I have a lot of to learn and improve. I do not want to restart the "whole" call/location sequence, I want to restart whole application, 7 files, sensors bias... I do want to restart my program because this is the behaviour I need. Doing a warm restart costs too much code and effort to me and I do not gain anything with it, just complicate more the code. Commented Oct 14, 2016 at 14:02
  • You want to close the files, then reopen them and re-initialise variables? Then close the files after your missed call. And use a loop to come back round and do your initialisation stuff again. I'm not trying to be rude, but there is no situation in which restarting an application is a reasonable alternative to a simple loop. If this is a uni project, you WILL get a lower grade if you demonstrate a lack of technical ability. I'm not trying to be rude, I'm trying to point you in the direction of what gets you a good grade. :)
    – Graham
    Commented Oct 14, 2016 at 15:10
1

Depending on what you mean by "restarting" the program, I can see few simple solutions.

One is to embed your whole program in some "Program" class, that essentially provides some loop that has your proper program. When you need to restart the program, you call static public method "Restart" that starts the loop again.

You could also try to make system-specific call that would start your program again, and exit. As suggested in other answer, you could create a wrapper program for this sole purpose(and check return code to know whether to quit or restart).

The other simple option is to use goto. I know that people will hate me for even mentioning it, but let's face it: we want to make simple program, not use beautiful boilerplate. Goto going back guarantees destruction, so you could create a program with a label in the beginning, and some function "Restart" that just goes back to the beginning.

Whatever option you choose, document it well, so others(or you in the future) will use one WTF less.

PS. As mentioned by alain, goto will not destroy global nor static objects, same would go for enclosing class. Therefore any approach that does not include starting new program in place of the current one should either refrain from using global/static variables, or take proper actions to re-set them(although that might be tedious, as with addition of each static/global, you need to modify the restart routine).

1
  • 2
    goto will not destroy global and static objects.
    – alain
    Commented Oct 14, 2016 at 10:29
-2

Simple and clean way to do this is to add a wire from an unused data pin to the RESET pin and set it low to reset! :-)

3
  • 1
    As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.
    – Community Bot
    Commented Dec 2, 2022 at 17:52
  • Not sure how to make this any simpler! ???
    – Timo001
    Commented Nov 12, 2023 at 15:25
  • i don't know, but I think Raspberry may be running more than this one app
    – szpanczyk
    Commented Mar 12 at 13:55

Not the answer you're looking for? Browse other questions tagged or ask your own question.