Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 years ago.
Improve this question
Several resources are describing the topic "Exception Handling" like Wikipedia and vast more number of resources. But very few of them explained that what is the Exception itself. Maybe they assumed that its very obvious. I could find a good short explanation on Oracle documentation:
Definition: An exception is an event, which occurs during the execution of a
program, that disrupts the normal flow of the program's instructions.
The rest of this paper is about exception on Java programming. But I do not understand Java well to read the entire of documentation. I need a clarify on exception.
edit:
I need an example of Exception. For example in C++.
And I need to know what is its difference by bug?
Conceptually, an exception is a scenario that shouldn't happen in a normal run of your program. For example, a remote server being unavailable, an input being in an incorrect format, a file not being found, the system running out of memory... Depending on the kind and the circumstances, it may or may not be possible for the program to handle it.
Technically, an exception is represented as a simple object. Exception objects are kind of special in the sense that they can be "thrown" from an inner level of execution to an outer level that "catches" them, typically abandoning the code in all levels between the thrower and the catcher.
C++, Java and C# are a few examples of many languages that have a form of exception handling mechanism. Strictly speaking, C does not have the concept of exceptions (out-of-the-box, at least).
"Throwing an exception" (sometimes also called "raising an exception") is a way to end a function when, for some reason, the function cannot complete the task it is expected to complete.
Example: You have a function f that takes a float argument and is expected to compute and return its natural logarithm. Now at some point during the calculations it turns out that the argument that it was passed is 0. There is no way to compute the logarithm of 0, so what should the function do?
One way to handle this situation is to return a special value (such as NaN, the not-a-number value of float), but this can be misleading to the caller of the function: The function was called on some variable, and returned some value. All looks normal, while in reality nothing is normal – the function could not do its job.
Therefore, another way of handling this is to throw an exception. The effect is that the function ends, but does not return any value. Now, obviously, the calling function has a problem, because the normal flow of things has been disturbed: No value was returned from the function call. There are two possibilities for what can happen next: Either the calling function was prepared for this by having put the call of f in a try-catch clause:
try {
log_of_val = f(val);
} catch (const exception &e) {
/* Description of what to do when
an exception is thrown by f. */
}
If the exception that is thrown by f matches the type of exception defined in one of the catch-clauses, then the first such catch-clause is executed.
If there is no such catch-clause, the exception is thrown again, i.e. the calling function also ends abruptly and the caller of the caller is stopped to check whether there is some catch-code for the exception. If not, it also ends and that functions calling function is stopped, and so on, until the top of the call stack is reached (i.e. the level of main) and if there is still no catch-clause there, the entire program is terminated and the operating system is informed of the abortion of the process.
So an exception has the power to bring down the entire process if there is no appropriate catch-clause. But an exception is far better than simply calling something like exit(1), because it does not immediately terminate the process. It first gives the caller a chance to react to the problem, and then the caller's caller, and so on.
The exception throwing mechanism also ensures that local variables are properly destructed and de-allocated before the current function ends. So, as far as automatic variables and dynamic memory that is managed by smart pointers and the like is concerned, you won't get memory leaks and similar problems.
To sum up, exceptions (and the whole throwing and catching mechanism) is a way to deal with unusual, but possible and to some extent expected events in the flow of a program. Typically, it's events that can occur in a function call that render the proper execution of the function impossible, but that cannot be prevented from within the function. These events are often the responsibility of the calling function if it passes unsuitable arguments, or of the user who gives unsuitable input to the program. Also problems related to the state of the system, such as insufficient memory, tend to be handled by throwing exceptions.
But unlike bugs, the programmer who wrote a function anticipated the possiblility of the problem and prepared the code with suitable throw and catch code to deal with it by having the program shut down in a controlled way, or otherwise react to the problem appropriately.
Regarding the core of your question: What is the exception itself? The exception is an object created at the time when the "exception is thrown". You could view it as some kind of replacement for the return value, because the exception object is in fact passed to the caller, in a similar way as the return value would. But unlike with an actual return value, the caller is informed that what has happened is an exception and that it must handle this in the way I've described above. Further more, the data type of the exception is not the data type declared as return type of the function. In fact, it can be (almost) any data type. In particular, it can be a complex object with member variables that are initialized with values that describe the circumstances of the exception. A typical exception object is C++ is of class type, often (but not necessarily) defined as something like this:
#include <exception>
class my_exception : public std::exception
{
public:
explicit my_exception(const char *description)
: std::exception() , description_(description)
{ }
virtual const char *what() const noexcept
{ return description_; }
private:
const char *description_;
};
So it's a user-defined object that is constructed on a string, stores a pointer to the string internally, and provides a member function what() that returns the string. The idea is that the string is defined when the exception is thrown, and that it contains some description of the problem.
The caller of f can then catch this type of exception by enclosing the call to f in a try-clause and adding a catch-clause for my_exception:
try
{
f();
} catch (const my_exception &e) {
std::cerr << "A problem has occurred when evaluating f(): "
<< e.what()
<< std::endl;
}
In this example, we use the exception object's what() function to print a description of the problem. After the catch-clause is completed, the caller will continue as normal. (If this is not desired, throw; can be used inside the catch-clause to re-throw the exception so it is passed to the caller's caller, and so on.)
Note, again, that exception can be user-defined objects, and they can be derived from std::exception, and they can override the what() function to return a problem description as a string, but none of this is necessary. You can also throw the string itself, or an int as exception.
Exception is an object which you throw during executing something IF anything goes wrongs.
Like that when you are "try"ing to execute the method, you can "catch" anything that ges wrong without crashing your program.
void doSmth()
{
.
.
.
if(somthingWentWorng)
throw Exception("Not Good!")
.
.
.
}
Then whenever you want to call doSmth()
try
{
doSmth();
}
catch (Exception &e)
{
cout << e.what() << endl;
}
this way, if somthing went wrong while executing doSmth you can figure it out without you application being crashed.
Related
I have a application with many classes. This application is started on the main with a sinle line, let's say something like this:
int main()
{
try
{
classA.start();
}
catch(...)
{
std::cout<<"EXCEPTION CAUGHT"<<std::endl;
}
}
After classA.start() is called, then other classes and other procedures are called. If there's any unexpected exception ocurring on those classes, the try-catch, as stated in the code above, wont catch them. I was trying and seems that I need to set try-catch on every place I think it can be a exception. My point here is, since I already cover most of the exception, I want to add this global try-catch to handle those I forgot and be able to log it and keep working.
I hope I explained myself properly.
Thanks
Yes this will indeed catch every exception thrown within your program (when main is in the call stack), but that doesn't necessarily include any undefined behaviour, for example
out of bounds array access.
invalid pointer dereference.
stack overflows.
an integer division by zero.
To repeat, exceptions thrown when objects with static storage duration are destructed, or global objects constructed or destructed will not be caught at your catch site either.
I am trying to figure out the best way to deal with exceptions.
C++ says that any datatype can be thrown as an exception, but there is no way to tell what data type has been thrown, which makes exceptions essentially worthless. However, I am assuming that these days everyone throw std::exception, so that is safe in a catch. Is that a fair assumption?
(I am building a library that will be used by others, so has to fit in with other code that I do not control.)
The Exception.what function returns a char * (not a string) with no way to free it. Of course, that string should contain information about the exception, for example if a file is not found then the name of the file that was not found. I assume that we just tolerate a small memory leak here when exceptions are thrown. Correct?
It is unclear how reliably stack traces can be generated in a general way and sent to a log file. (In a production environment when things go wrong, not in a debugger.) So I was thinking of inserting otherwise redundant try/catch blocks at interesting places in the code which can add logging and append extra information to the what text and then rethrow a new exception. But that process will, of course, destroy any stack trace. For example
foo = stuff();
try {
processStuff()
} catch (std::exception& ex) {
string msg = "While processing " + foo.toString() + ": " + ex.what;
log << msg;
throw std::exception((char[])msg);
}
Is that the best approach?
There are lots of articles that describe the basic classes but nothing I could find on how to really make them work in practice. Links appreciated.
(Here again I am trying to write Java/.Net in C++. Is that a hopeless cause?)
Type of exception
What type of exception object can be thrown is part of the function / method's public contract.
Often, libraries may introduce their own exception types which may or may not inherit from std::exception.
Recommended: throw std::exception or an exception inherited from it. Document the type(s) of exception thrown. Usually, you will have a "library default", such as
Unless stated otherwise, all methods and functions in this library may throw an exception of type mylib::exception or a type inherited from it.
char * what()
The (implied?) assumption is that the pointer is valid as long as the exception object is valid. No necessity to free the string manually, no reason for leak.
If you need to store the text for later, make a copy of it - e.g. by assigning to std::string.
Stack traces
... are not part of the C++ standard. Furthermore, most compiler implementations allow generating code that does not allow re-discovering a stack trace. (the respective option usually says something about "stack frame").
However, for most compilers, libraries exist that can add this stack trace, but this usually requires access to the debug symbols.
"Redundant" try/catch
You might need them anyway.
The perfect exception must support different aspects:
it contains instructions or hints for the end user how to remove a blocking issue ("Cannot open file bibbit.txt because it is read only")
it contains information for support and development why the error occurred, allowing them to possibly avoid it / handle it better in the future. (Such as ... the stack trace)
it needs to allow calling code to detect known exceptions and handle them specifically (e.g. the file the user wants to open is read-only, ask user if they want to open in read-only mode, and try again)
Rarely an exception does all that perfectly. But repackaging at certain "layers" helps a lot here - even though this makes us lose some of the beauty of exceptions.
Does that help?
Edit regarding your edit:
Generally ok, but DO NOT re-construct the exception. Change your code to:
...
catch (std::exception& ex) {
string msg = "While processing " + foo.toString() + ": " + ex.what;
log << msg;
throw; // <--- !!!!!!
}
This re-throws the original exception, so catch handlers further down can still distinguish the different types:
void Foo() {
class random_exception : public std::exception { ... }
try {
...
if (rand() % 2) throw random_exception();
...
}
catch(std::exception const & x)
{
log << x.what();
throw;
}
}
int main()
{
try {
Foo();
}
catch(random_exception const & x)
{
cout << "A random exception occurred, you can try again";
}
catch(std::exception const & x)
{
cout << This didn't work. " << x.what();
}
catch(...) // catches all exception types, but you don't know what
{
cout << "Uh, oh, you are doomed.".
}
}
Of course, that's an issue when repackaging the exception.
Some things I'm leaning to:
The exception type to be thrown is a thin wrapper around a (smart) pointer. This allows storing exceptions (e.g. to pass them to another thread, or as an "inner exception" when repackaging) without losing type information:
I allow separate messages for end user and for diagnostics. End user message is required, diagnostics is usually generated from (and contains) the error code and context. User will see no "weird numbers and techie gibberish" unless they click on "details".
Instead of including parameters in the error message:
msg = "Could not open file bibbit.txt (tried 5 times)"; // :-(
I use a fixed message, and a list of (name, value) parameters.
msg = "Could not open file"; // :-)
msg.Add("filename", filename).Add("retries", retryCount);
This should simplify localization, and allows the caller to access individual attributes for known errors, allowing more specific handling.
However, I am assuming that these days everyone throw std::Exception, so that is safe in a catch. Is that a fair assumption?
That's mostly a safe assumption. Some people insist in throwing random stuff, but it's not your business - if you are a library you throw exceptions and at most you catch your own, you shouldn't be concerned with what other people throw (your code should use RAII anyway to avoid resource leaks - this covers even the case where e.g. callbacks throw stuff you don't know).
The Exception.what function returns a char * (not a string) with no way to free it. Of course, that string should contain information about the exception, for example if a file is not found then the name of the file that was not found. I assume that we just tolerate a small memory leak here when exceptions are thrown. Correct?
Nope. The string returned by what normally does not result in a memory leak. Either is statically allocated (I've seen many simple exception classes that just return a string literal) or it's managed inside the exception itself (std::runtime_error normally contains an std::string, with what returning the result of its c_str method). In general, you can assume that whatever what results is there as long as the exception lives - if you need it outside the catch block copy it into an std::string or something.
This is actually required by the standard:
The return value remains valid until the exception object from which it is obtained is destroyed or a non-const member function of the exception object is called.
(C++11, §18.8.1 ¶10)
It is unclear how reliably stack traces can be generated in a general way and sent to a log file. (In a production environment when things go wrong, not in a debugger.) So I was thinking of inserting otherwise redundant try/catch blocks at interesting places in the code which can add logging and append extra information to the what text and then rethrow a new exception. But that process will, of course, destroy any stack trace.
Stack traces in C++ are a sad story; there's no portable way to generate them, you have to resort to platform-specific calls (or to libraries that abstract them); personally I used several approaches in the past:
on a new, multi-platform Qt application I wrote my own "fat" exception class, which saved the stack trace (I derived from booster::exception, which already bundles the stack trace-saving part) and added the possibility to add extra information while the exception gets caught and rethrown, similar to how Boost.Exception is implemented (important: Boost.Exception != booster::exception, they are completely unrelated); see here, it's full of Qt types but you can get the idea;
on a legacy project which throw the most bizarre types (and there's no way to change them to a common exception type) I just hooked (via linker tricks) the throw and I always save the stack trace in a global circular buffer, which is printed out if an exception is not caught.
Your approach is flawed because not only it loses parts of the stack trace, but even the type information about the exception. Look up how Boost.Exception does its thing to see how to do it right. Also, you never, ever throw a new (=heap allocated) exception, otherwise freeing it becomes a burden to people who want to catch it (also, probably nobody will catch it because no one catches by pointer, you normally catch by reference).
It looks like std::stack_trace will be part of C++ 23.
Under GCC (yes, I know, not universal), you can use std::current_exception to get information about the current exception. For instance, the following code will return the mangled name of the exception type:
std::string current_exception_type()
{
std::string result;
if (std::current_exception())
{
auto p = std::current_exception().__cxa_exception_type();
if (p)
{
result = p->name();
}
}
return result;
}
To demangle the name, you can use:
std::string demangle_cpp(char const* name)
{
std::string result;
char* demangled(nullptr);
try
{
int status;
demangled = abi::__cxa_demangle(name, 0, 0, &status);
if (demangled != nullptr) result = demangled;
} catch(...)
{
}
if (demangled != nullptr) free(demangled);
return result;
}
Consider the following horribleness:
#include <iostream>
struct thing
{
thing()
{
std::cout << "thing ctor\n";
throw 5;
}
};
void SomeTerminateHandler()
{
std::cout << "Uncaught exception!?\n";
}
int IHopeThisGetsCalledFirst()
{
std::cout << "IHopeThisGetsCalledFirst()\n";
std::set_terminate(SomeTerminateHandler);
return 2;
}
const int x = IHopeThisGetsCalledFirst();
const thing y;
int main()
{
}
Output:
IHopeThisGetsCalledFirst()
thing ctor
Uncaught exception!?
This relies on static initialization order (which I can mess with, for MSVS anyway) so it's not ideal even if the following questions have acceptable answers.
What can I do in SomeTerminateHandler to 'catch' the exception so I can display an error dialog box or log out the details of the error?
abort is called after SomeTerminateHandler in the above program. Why? This says "The terminate handler by default calls cstdlib's abort function." - but I'm not using the default terminate handler, and mine doesn't call abort.
Is there anything I can do to handle exceptions in static initialization time. If not, why not? Why isn't there something in the language to allow this?
What can I do in SomeTerminateHandler to 'catch' the exception so I can display an error dialog box or log out the details of the error?
Nothing - only exception handlers can access the thrown exception.
abort is called after SomeTerminateHandler in the above program. Why?
Your terminate handler must not return; the standard (C++11, 18.8.3.1) requires that it "shall terminate execution of the program without returning to the caller" - the page you link to also says the same thing. If you break that requirement, then anything could happen.
Is there anything I can do to handle exceptions in static initialization time?
You can catch the exception in the constructor; or you can avoid complex static objects.
If not, why not? Why isn't there something in the language to allow this?
I can't answer why, but C++ doesn't handle complex static objects at all well. Even if your compiler does have non-standard extensions to specify the initialisation order, I suggest avoiding them if at all possible.
Is there anything I can do to handle exceptions in static
initialization time. If not, why not? Why isn't there something in the
language to allow this?
C++ doesn't have any well-defined constructs for user-defined objects externally linked or created at file scope. It's generally problematic with issues like undefined initialization order. Without a clear definition of what should happen with respect to things like initialization order, it would be difficult to define meaningful try/catch behavior (where would one put the try/catch block, e.g., if any object constructed in any compilation unit in a system can throw?).
For a more philosophical answer, I'd venture to guess that one of the problems C++ aims to address is the need for a lot of global objects. The language doesn't bother to provide well-defined behavior for them as they should generally be avoided in the first place.
If you want a quick fix, we can construct things in a lazy fashion:
thing& my_thing()
{
static thing obj;
return obj;
}
This ensures that thing won't be constructed until this function is first called which means it will not be constructed outside of your main entry point unless you have another global object which is calling this (directly or indirectly) through its constructor.
Ultimately it would be better if you avoid global instances of user-defined types this way all together, but if you can't resist the temptation, I recommend at least applying a form of lazy initialization liberally.
Is there anything I can do to handle exceptions in static initialization time. If not, why not?
No, because the initialization order is not specified by the standard.
The only thing is not to do it, or at least minimize number of objects that are initialized before main. It would be also very good to put them all in one place.
abort is called after SomeTerminateHandler in the above program. Why? This says "The terminate handler by default calls cstdlib's abort function." - but I'm not using the default terminate handler, and mine doesn't call abort.
Your handler is most likely not initialized on time (the exception is thrown before your handler is initialized).
I am writing a program using gcc in c++. On dec. 5th I posted a question because of a weird problem ( https://stackoverflow.com/a/8392854/837803 ). When a software exception leaves a function declared with no 'throw' specifications like this:
int foo();
or this:
int foo() throw();
gcc-generated code will crash.
I want to tell gcc that any kind of software exception could leave any function I write. I think it is something like:
int foo() throw(...);
BUT: I don't want to write throw(...) in all function specifications. I realise that my program size will be bigger, but that is not a problem for this case. Also, I have read that the behaviour of gcc that I am suggesting, is an ANSI violation. But that is no problem either.
Among the many, many, many command-line options of gcc, there must be one that I am looking for, but I haven't found it yet.
What is the option I am looking for?
I take exception to this:
gcc-generated code will crash.
This is just plain wrong.
A function declared like this:
void func1();
If you throw an exception it will cause the stack to unwind upto an appropriate catch. IF there is no appropriate catch the program exits (weather the stack unwinds in this case is implementation defined (thus put a catch all in main)).
A function declared like this:
void func2() throw(); // ie no throw.
If an exception escapes this function then unexpected() is called. The default action of unexpected is to call abort() which causes the program to exit (Note: you can replace unexpected with a user defined function but it has to either exit or throw an alternative exception that can pass the throw specification (in this case that is not possible)).
The behavior you want is the default behavior (with no throw specification). Throw specifications were an experiment that failed and have thus been deprecated. You should not be using them anyway (apart from no-throw).
So you can get normal working code with exceptions if you define your functions like this:
void func3(); // Exceptions work fine.
But it is best to put a catch in main()
int main()
{
try
{
// DoWork
}
catch(std::exception const& e) // We can print a good error message with these
{
log(e.what());
throw; // Not much you can do so re-throw for the OS.
}
catch(...) // Catch all other exceptions.
{
log("Unknown Exception");
throw; // Not much you can do so re-throw for the OS.
}
// Catching forces the stack to unwind all the way to main()
// Otherwise it is implementation defined whether it unwinds.
}
It will depend on your compiler. With gcc default settings you can just throw stuff without having throw(...) in the prototype.
I use throw declarations in the prototype when I want to reduce the amount of throwable 'things'. So int myfunc() throw(string) will only allow strings (or a derived class of string to be thrown).
The following assumes that you are throwing an exception of the type as outlined in this question.
Your exception type doesn't work.
In throw_exception, we have this line:
text l_message;
I don't know what a text is, but I'll assume it is a string-like class. I will similarly assume that test::_char is just a fancy way of saying char.
So we have this stack object l_message which is of type text. Later, we have this line:
throw exc((const text::_char *)l_message);
Since you did not deign to provide us with a definition of text, again, I must make an assumption. I assume that text has an operator text::_char* defined for it which returns a pointer to a C-style string representing the stored string data, which is NULL-terminated.
Only there's one problem: that pointer is owned by l_message.
The moment l_message falls off the stack, the pointer returned by l_message disappears. That would be fine... if the class exc actually copied that string into an internal buffer. But it doesn't. It just stores a pointer.
A pointer which no longer points to valid memory. That's not a good idea.
An exception needs to be self-contained. It should own all of the memory it needs to do whatever it is supposed to do.
Also, you did not properly derived from std::exception. Specifically, you have to overload the virtual const char* what() const throw() method. Then again, I'm surprised it let you compile your code without it.
I would like my C++ code to stop running if a certain condition is met, but I'm not sure how to do that. So just at any point if an if statement is true terminate the code like this:
if (x==1)
{
kill code;
}
There are several ways, but first you need to understand why object cleanup is important, and hence the reason std::exit is marginalized among C++ programmers.
RAII and Stack Unwinding
C++ makes use of a idiom called RAII, which in simple terms means objects should perform initialization in the constructor and cleanup in the destructor. For instance the std::ofstream class [may] open the file during the constructor, then the user performs output operations on it, and finally at the end of its life cycle, usually determined by its scope, the destructor is called that essentially closes the file and flushes any written content into the disk.
What happens if you don't get to the destructor to flush and close the file? Who knows! But possibly it won't write all the data it was supposed to write into the file.
For instance consider this code
#include <fstream>
#include <exception>
#include <memory>
void inner_mad()
{
throw std::exception();
}
void mad()
{
auto ptr = std::make_unique<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 essentially leaves the current function scope, so it knows about the end of the life cycle of os thus calling its destructor and doing proper cleanup by closing and flushing the file to disk.
Possibility 2: Throwing a exception also takes care of the life cycle of the objects in the current scope, thus doing proper cleanup...
Possibility 3: Here stack unwinding enters in action! Even though the exception is thrown at inner_mad, the unwinder will go though the stack of mad and main to perform proper cleanup, all the objects are going to be destructed properly, including ptr and os.
Possibility 4: Well, here? exit is a C function and it's not aware nor compatible with the C++ idioms. It does not perform cleanup on your objects, including os in the very same scope. So your file won't be closed properly and for this reason the content might never get written into it!
Other Possibilities: It'll just leave main scope, by performing a implicit return 0 and thus having the same effect as possibility 1, i.e. proper cleanup.
But don't be so certain about what I just told you (mainly possibilities 2 and 3); continue reading and we'll find out how to perform a proper exception based cleanup.
Possible Ways To End
Return from main!
You should do this whenever possible; always prefer to return from your program by returning a proper exit status from main.
The caller of your program, and possibly the operating system, might want to know whether what your program was supposed to do was done successfully or not. For this same reason you should return either zero or EXIT_SUCCESS to signal that the program successfully terminated and EXIT_FAILURE to signal the program terminated unsuccessfully, any other form of return value is implementation-defined (§18.5/8).
However you may be very deep in the call stack, and returning all of it may be painful...
[Do not] throw an exception
Throwing an exception will perform proper object cleanup using stack unwinding, by calling the destructor of every object in any previous scope.
But here's the catch! It's implementation-defined whether stack unwinding is performed when a thrown exception is not handled (by the catch(...) clause) or even if you have a noexcept function in the middle of the call stack. This is stated in §15.5.1 [except.terminate]:
In some situations exception handling must be abandoned for less subtle error handling techniques. [Note: These situations are:
[...]
— when the exception handling mechanism cannot find a handler for a thrown exception (15.3), or when the search for a handler (15.3) encounters the outermost block of a function with a noexcept-specification that does not allow the exception (15.4), or [...]
[...]
In such cases, std::terminate() is called (18.8.3). In the situation where no matching handler is found, it is implementation-defined whether or not the stack is unwound before std::terminate() is called [...]
So we have to catch it!
Do throw an exception and catch it at main!
Since uncaught exceptions may not perform stack unwinding (and consequently won't perform proper cleanup), we should catch the exception in main and then return a exit status (EXIT_SUCCESS or EXIT_FAILURE).
So a possibly good setup would be:
int main()
{
/* ... */
try
{
// Insert code that will return by throwing a exception.
}
catch(const std::exception&) // Consider using a custom exception type for intentional
{ // throws. A good idea might be a `return_exception`.
return EXIT_FAILURE;
}
/* ... */
}
[Do not] std::exit
This does not perform any sort of stack unwinding, and no alive object on the stack will call its respective destructor to perform cleanup.
This is enforced in §3.6.1/4 [basic.start.init]:
Terminating the program without leaving the current block (e.g., by calling the function std::exit(int) (18.5)) does not destroy any objects with automatic storage duration (12.4). If std::exit is called to end a program during the destruction of an object with static or thread storage duration, the program has undefined behavior.
Think about it now, why would you do such a thing? How many objects have you painfully damaged?
Other [as bad] alternatives
There are other ways to terminate a program (other than crashing), but they aren't recommended. Just for the sake of clarification they are going to be presented here. Notice how normal program termination does not mean stack unwinding but an okay state for the operating system.
std::_Exit causes a normal program termination, and that's it.
std::quick_exit causes a normal program termination and calls std::at_quick_exit handlers, no other cleanup is performed.
std::exit causes a normal program termination and then calls std::atexit handlers. Other sorts of cleanups are performed such as calling static objects destructors.
std::abort causes an abnormal program termination, no cleanup is performed. This should be called if the program terminated in a really, really unexpected way. It'll do nothing but signal the OS about the abnormal termination. Some systems perform a core dump in this case.
std::terminate calls the std::terminate_handler which calls std::abort by default.
As Martin York mentioned, exit doesn't perform necessary clean-up like return does.
It's always better to use return in the place of exit.
In case if you are not in main, wherever you would like to exit the program, return to main first.
Consider the below example.
With the following program, a file will be created with the content mentioned.
But if return is commented & uncommented exit(0), the compiler doesn't assure you that the file will have the required text.
int main()
{
ofstream os("out.txt");
os << "Hello, Can you see me!\n";
return(0);
//exit(0);
}
Not just this, Having multiple exit points in a program will make debugging harder.
Use exit only when it can be justified.
Call the std::exit function.
People are saying "call exit(return code)," but this is bad form. In small programs it is fine, but there are a number of issues with this:
You will end up having multiple exit points from the program
It makes code more convoluted (like using goto)
It cannot release memory allocated at runtime
Really, the only time you should exit the problem is with this line in main.cpp:
return 0;
If you are using exit() to handle errors, you should learn about exceptions (and nesting exceptions), as a much more elegant and safe method.
return 0; put that wherever you want within int main() and the program will immediately close.
The program will terminate when the execution flow reaches the end of the main function.
To terminate it before then, you can use the exit(int status) function, where status is a value returned to whatever started the program. 0 normally indicates a non-error state
Either return a value from your main or use the exit function. Both take an int. It doesn't really matter what value you return unless you have an external process watching for the return value.
If you have an error somewhere deep in the code, then either throw an exception or set the error code. It's always better to throw an exception instead of setting error codes.
Generally you would use the exit() method with an appropriate exit status.
Zero would mean a successful run. A non-zero status indicates some sort of problem has occurred. This exit code is used by parent processes (e.g. shell scripts) to determine if a process has run successfully.
Beyond calling exit(error_code) - which calls atexit handlers, but not RAII destructors, etc.
- more and more I am using exceptions.
More and more my main program looks like
int main(int argc, char** argv)
{
try {
exit( secondary_main(argc, argv );
}
catch(...) {
// optionally, print something like "unexpected or unknown exception caught by main"
exit(1);
}
}
where secondary_main
in where all the stuff that was originally is put --
i.e. the original main is renamed secondary_main, and the stub main above is added.
This is just a nicety, so that there isn't too much code between the tray and catch in main.
If you want, catch other exception types.
I quite like catching string error types, like std::string or char*, and printing those
in the catch handler in main.
Using exceptions like this at least allows RAII destructors to be called, so that they can do cleanup. Which can be pleasant and useful.
Overall, C error handling - exit and signals - and C++ error handling - try/catch/throw exceptions - play together inconsistently at best.
Then, where you detect an error
throw "error message"
or some more specific exception type.
If the condition I'm testing for is really bad news, I do this:
*(int*) NULL= 0;
This gives me a nice coredump from where I can examine the situation.
Dude... exit() function is defined under stdlib.h
So you need to add a preprocessor.
Put include stdlib.h in the header section
Then use exit(); wherever you like but remember to put an interger number in the parenthesis of exit.
for example:
exit(0);
If your if statement is in Loop You can use
break;
If you want to escape some code & continue to loop Use :
continue;
If your if statement not in Loop You can use :
return 0;
Or
exit();
To break a condition use the return(0);
So, in your case it would be:
if(x==1)
{
return 0;
}