How to end C++ code -


i c++ code stop running if condition met, i'm not sure how that. @ point if if statement true terminate code this:

if (x==1) {     kill code; } 

there several ways, first need understand why object cleanup important, , hence reason std::exit marginalized among c++ programmers.

raii , stack unwinding

c++ makes use of idiom called raii, in simple terms means objects should perform initialization in constructor , cleanup in destructor. instance std::ofstream class [may] open file during constructor, user performs output operations on it, , @ end of life cycle, determined scope, destructor called closes file , flushes written content disk.

what happens if don't destructor flush , close file? who knows! possibly won't write data supposed write file.

for instance consider code

#include <fstream> #include <exception> #include <memory>  void inner_mad() {     throw std::exception(); }  void mad() {     std::unique_ptr<int> ptr(new int);     inner_mad(); }  int main() {     std::ofstream os("file.txt");     os << "content!!!";      int possibility = /* either 1, 2, 3 or 4 */;      if(possibility == 1)         return 0;     else if(possibility == 2)         throw std::exception();     else if(possibility == 3)         mad();     else if(possibility == 4)         exit(0); } 

what happens in each possibility is:

  • possibility 1: return leaves current function scope, knows end of life cycle of os calling destructor , doing proper cleanup closing , flushing file disk.
  • possibility 2: throwing exception takes care of life cycle of objects in current scope, doing proper cleanup...
  • possibility 3: here stack unwinding enters in action! though exception thrown @ inner_mad, unwinder go though stack of mad , main perform proper cleanup, objects going destructed properly, including ptr , os.
  • possibility 4: well, here? exit c function , it's not aware nor compatible c++ idioms. does not perform cleanup on objects, including os in same scope. file won't closed , reason content might never written it!
  • other possibilities: it'll leave main scope, performing implicit return 0 , having same effect possibility 1, i.e. proper cleanup.

but don't told (mainly possibilities 2 , 3); continue reading , we'll find out how perform proper exception based cleanup.

possible ways end

return main!

you should whenever possible; prefer return program returning proper exit status main.

the caller of program, , possibly operating system, might want know whether program supposed done or not. same reason should return either 0 or exit_success signal program terminated , exit_failure signal program terminated unsuccessfully, other form of return value implementation-defined (§18.5/8).

however may deep in call stack, , returning of may painful...

[do not] throw exception

throwing exception perform proper object cleanup using stack unwinding, calling destructor of every object in previous scope.

but here's the catch! it's implementation-defined whether stack unwinding performed when thrown exception not handled (by catch(...) clause) or if have noexcept function in middle of call stack. stated in §15.5.1 [except.terminate]:

  1. in situations exception handling must abandoned less subtle error handling techniques. [note: these situations are:

    [...]

    when exception handling mechanism cannot find handler thrown exception (15.3), or when search handler (15.3) encounters outermost block of function noexcept-specification not allow exception (15.4), or [...]

    [...]

  2. in such cases, std::terminate() called (18.8.3). in situation no matching handler found, implementation-defined whether or not stack unwound before std::terminate() called [...]

so have catch it!

do throw exception , catch @ main!

since uncaught exceptions may not perform stack unwinding (and consequently won't perform proper cleanup), should catch exception in main , return exit status (exit_success or exit_failure).

so possibly setup be:

int main() {     /* ... */     try     {         // insert code return throwing exception.     }     catch(const std::exception&)  // consider using custom exception type intentional     {                             // throws. idea might `return_exception`.         return exit_failure;     }     /* ... */ } 

[do not] std::exit

this not perform sort of stack unwinding, , no alive object on stack call respective destructor perform cleanup.

this enforced in §3.6.1/4 [basic.start.init]:

terminating program without leaving current block (e.g., calling function std::exit(int) (18.5)) not destroy objects automatic storage duration (12.4). if std::exit called end program during destruction of object static or thread storage duration, program has undefined behavior.

think now, why such thing? how many objects have painfully damaged?

other [as bad] alternatives

there other ways terminate program (other crashing), aren't recommended. sake of clarification going presented here. notice how normal program termination does not mean stack unwinding okay state operating system.

  • std::_exit causes normal program termination, , that's it.
  • std::quick_exit causes normal program termination , calls std::at_quick_exit handlers, no other cleanup performed.
  • std::exit causes normal program termination , calls std::atexit handlers. other sorts of cleanups performed such calling static objects destructors.
  • std::abort causes abnormal program termination, no cleanup performed. should called if program terminated in really, unexpected way. it'll nothing signal os abnormal termination. systems perform core dump in case.
  • std::terminate calls std::terminate_handler calls std::abort default.

Comments

Popular posts from this blog

c++ - Difference between pre and post decrement in recursive function argument -

php - Nothing but 'run(); ' when browsing to my local project, how do I fix this? -

php - How can I echo out this array? -