How to terminate a program from a function?

Does C/C++ support terminating a program from a subroutine function i.e not main?
So far I only found that exit and abort allow a user to terminate current function or process.
If I'm not in main function, is there a way to terminate the whole program?
You could make your subroutine skip to the end of main which would terminate the program. Not sure if you can actually do it with the subroutine.
The exit() function is the "terminate process normally" function.

However, I agree with Umz that you should try to unwind as close to main() as possible before terminating.

In C++, you can use an exception for that:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include <exception>  // or #include <stdexcept>
#include <iostream>

struct QuitNow: public std::exception
  {
  QuitNow() { }
  virtual ~QuitNow() throw() { }
  virtual const char* what() throw()
    {
    return "QuitNow: request normal termination of program.\n"
           "(You should not see this message. Please report it if you do.)";
    }
  };

using namespace std;

void loopy( unsigned count )
  {
  if (count < 20)
    {
    cout << "count = " << count << endl;
    loopy( count +1 );
    }
  else
    {
    cout << "Throwing QuitNow.\n";
    throw QuitNow();
    }
  }

int main()
  {
  try
    {
    cout << "Starting.\n";
    loopy( 0 );
    cout << "You shouldn't see this.\n";
    }
  catch (QuitNow)
    {
    cout << "Caught it!\n";
    }
  catch (...)
    {
    cout << "Something went wrong...\n";
    }
  cout << "Good-bye.\n";
  return 0;
  }

Hope this helps.
Last edited on
Using exceptions as a control structure is a bad idea. As soon as your code becomes part of another project, someplace there will be a
1
2
3
4
catch(...)
{
 ...
}

that assumes that any exception is an error in the 'try'ed code. If that assumption doesn't hold, you will get your own brew of "undefined" behavior (although not generated by the illegal usage of the language, but rather by an abuse)

The exit() function is the "terminate process normally" function.

Not really. exit() means: terminate the program. Terminate it now. Don't call any destructors. Don't release file handles, mutexes, and other ressources. (What a lie. That's the abort() function. exit actually calls the destructors of *the current scope*. Which doesn't help you much if you are not in main()).

So, actually, no, c++ doesn't support to terminate a program safely from a function other than main().
Using exceptions as an abnormal return control structure is the whole point of exceptions. And there is no reason anyone should be placing code between your main() and your top-level control functions, let alone intercepting your exceptions. Should that happen then he deserves to deal with any weirdness or failure that ensues.

The exit() function is the "terminate process normally" function.

Not really. exit() means: terminate the program. Terminate it now. Don't call any destructors. Don't release file handles, mutexes, and other ressources...

Care to provide support for that? Here's mine:
http://www.opengroup.org/onlinepubs/000095399/functions/exit.html
http://www.cplusplus.com/reference/clibrary/cstdlib/exit.html
http://msdn.microsoft.com/en-us/library/k9dcesdd(VS.80).aspx

It is clearly stated that exit() releases all the resources that it can (including file handles, mutexes, and other resources) and terminates the program normally --equivalent to returning from main().

Oh, and about using exceptions instead of exit():
http://www.codeguru.com/cpp/cpp/cpp_mfc/exceptions/article.php/c4111/

(The purpose and cleanliness of exceptions vs <other things>):
http://nedbatchelder.com/text/exceptions-vs-status.html
http://cutebugs.net/files/cpp/index.html
Using exceptions as an abnormal return control structure is the whole point of exceptions.

Exactly. Abnormal return.

Care to provide support for that? Here's mine:

Sorry, but your's is crap. At best it serves as evidence that all but some infinitesimal reminder of the net is complete and utter BS.

I have only one reference, but I guess it's the joker: ISO 14882, our beloved standard, from which I like to quote so much:
Calling the function
void exit(int);
declared in <cstdlib> (18.3) terminates the program without leaving the current block and hence without destroying any objects with automatic storage duration (12.4). If exit is called to end a program during the destruction of an object with static storage duration, the program has undefined behavior.

(Huh? I really thought it would destroy objects in the current scope. Talk about the ammount of BS on the net...)
Listen, I don't know why you are in such a foul mood today. I don't want to fight you, and I don't deserve the abuse.

Calling references to Microsoft's docs, Open Group's IEEE standard docs, and this site's docs "crap" does little to advance ISO references --as they strictly conform to the ISO standards.

Again, the exit() function is equivalent to returning from main().

I didn't make that up, regardless of whether you want to believe it. And the whole reason that using an exception to get back to main() before exit()/returning is because exit() doesn't destroy static storage objects nor any objects allocated on the stack for actively-wound functions. If you are going to return abnormally, why not do it as gracefully as possible?

That is all I said.

Sorry ddk. I hope you'll stay with us despite occasional differences between members.
When would be a good time to use the exit()?
I am sort of guessing at this, but:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void leave(int variable) {
   if(variable == 0) {
      exit(0);
   } else if(variable == 1) {
      //log stuff
      exit(0);
   } else {
      cerr << "Some data could not be processed. Plz save us.";
      //take input if needed, etc
      exit(0);
   }
}

int main() {
   //stuff
   leave(variable);
}
Yes, I was indeed in a bad mood yesterday. I appologize for anything bad I have said.

Calling references to Microsoft's docs, Open Group's IEEE standard docs, and this site's docs "crap" does little to advance ISO references --as they strictly conform to the ISO standards.


Your first reference is to the *C* langauage specs. There are differences. C++ was never fully compatible, nor was it meant to be. This is such a case (from the C++ standard, before the description of exit(): "The contents are the same as the Standard C library header <stdlib.h>, with the following changes:")
Calling MS-docs 'crap' is something I've learned from the US courts. And all kidding aside, after what they have done to C++ with their 6.x VC++ versions (the only one I worked with), I don't give a damn what they consider right. (Don't get me wrong, I don't want to make this into a pro/con Microsoft war. But I think we can agree on the fact that they have their problems with standards. Just look at OOXML.)
As for your reference to this site, well, it doesn't conform with ISO 14882. I would certainly like to know where the author has taken his knowledge from. This is the very least thing one could expect from any reference for a standardized language/whatever.

All in all, having looked at the ISO C++ standard again, I now am pretty sure that most people have confused "static" with "automatic". *static* variables are indeed cleaned up. But not automatic ones.

I didn't make that up, regardless of whether you want to believe it.

Despite my mood, I didn't say (or mean) that. Obviously, on a board, it serves little purpose to say "Godd answer" when someone is right. On the other hand, if something suboptimal, non-portable, or even wrong is posted, a correction is a Good Thing. So please, don't interprete my posts as insults or the attitude "I don't like you and am better than you, so shut up" or something similar. I merely wanted to correct what was said about a language detail.

When would be a good time to use the exit()?

As of ISO 14882: when you don't have any objects with automatic storage duration and all objects with dynamic storage duration have been destroyed (or will be destroyed by a function registred with atexit()).

Oh. And one last thing. You are of course right that the standard is not as important as the implementations. Just try:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <cstdlib>
#include <iostream>

struct C
{
        ~C()
        {   
                std::cout<<"X"<<std::endl;
        }   
};

void f() 
{
        C c;
        exit(1);
}

int main()
{
        f();
}


Note, that while the C-header "stdlib.h" instead of <cstdlib> would be required to clean variables with automatic storage duration, however, in my implementation, it doesn't call destructors (I'm pretty sure, though cannot prove, that this is intended, because C had no destructors and cleaning up auto variables was something completely different). On my platform, C's destructor isn't called in both cases.
Topic archived. No new replies allowed.