I read some posts about assert and after all I can only imagine the following usage as legitime:
class Class
{
public:
Class( Requirement* aRequirement )
: m_Requirement( aRequirement )
{
}
// ...
void doSomething()
{
// Theoretically it is always set, but it is
// possible that a messy user passed a null pointer.
assert( m_Requirement != nullptr );
// ...
}
// ...
private:
Requirement* m_Requirement;
};
So using an assert is legitime when theoretically a variable is valid, but it is possible that a messy user passes some inappropriate value.
For example if we want to check a range then we should not use assert or exception, just use conditionals.
If there can be exceptional cases then exceptions shall be used.
And here is the question ... when everything shall be correct is that the exact time when the assert shall be used ?
Is that correct ?
Or is there any other cases when assert shall be used ?
TL;DR: Exceptions are for exceptional but recoverable errors from the outside, assertions are for bug-catching on the inside.
assert() is here to trap things that shouldn't happen, in any condition, if the program is correct. The goal is to halt the program for analysis as soon as it gets into an impossible state, before it goes haywire and crashes somewhere else, garbles the stack, or any other hard-to-debug failure.
You should use assertions to check that functions are fed the correct parameters (to catch the user's errors), that algorithms work the way they're intended to (to catch your own errors), etc.
Exceptions are here to trap thing that may (and will someday) happen, and that are not under any programmer's control, like network failure, memory shortage, file I/O problems, etc. They're an error handling facility, which provide an alternative code path for them.
You should use them to communicate errors to somewhere you can handle them. For example, a memory exception thrown from the bottom of a client-handling procedure could fly back up and be caught by the main server procedure, which would then gracefully notify the client and close its connection and continue working normally.
Is that correct ?
There's no finite (or standard defined) correct way of using assert()
Or is there any other cases when assert shall be used ?
IMHO it shouldn't really be used at all in preference of throwing an exception.
I personally hate assert() (vs. exceptions thrown).
It's hard to debug, unless you install your own abort() handler and can place breakpoints there.
Also assert() is only active with debug builds, and may lead to UB in production programs, where they've not been caught with test suites running on the debug version.
Related
I saw a function that uses throw to return something.
I've made some research before asking this, here, about throw and I did not find very much.
If someone could explain me when to use throw to return something and when to use the normal return statement, that would be awesome.
Using throw to return a result can be useful in a deeply nested recursion. Instead of backing out of each call level you get right back up to the top level call for this goal. I think in most other situations it's both too inefficient (because exceptions are optimized for failure handling) and too unconventional to even consider.
return is the easiest and in many situations also the most efficient way to return a computed value, a reference to a class member, a state information (e.g. an enum value), a trivial success/failure information, and, and, and. So this is the most common and usual way to evaluate function values.
throw on the other hand (like Alf already answered) deals with exception's - which, as the name already pretty clearly states :) an exception of the normal control flow: "Something very important (often something bad) happened, which requires an instant handling, I can not continue my usual processing flow and have to throw an exception immediately.". The reason can sometimes be a catastrophic and unrecoverable state in the program, but by no means always. For example, a socket losing its connection is pretty common and not a catastrophy - but can be a reason for throwing an exception nevertheless, because the socket code may be not able to continue computing.
Exceptions are usually a bit more difficult to handle - and to integrate into your program design - than usual return values, and they are - as others already stated - less efficient than simple return values, but they have a lot of benefits.
They can be caught from anywhere in the stack of calling functions
Let's say you write a game, with a game engine (e.g. Ogre), and this engine uses a direct X interface. Now something deep, deep in the DirectX interface happens, which hinders the engine from working correctly.
The error handling of this function (may be 8-10 calls deep in the call stack), which can not work properly anymore, would be nearly impossible if it would be done with normal return values - both for the engine programmers and for the game programmer. So in that case, without exceptions, the method of choice would be a non-standardized error handler - pretty similar to an exception, but not with the powerful possibilities of exceptions. Here's a practical example on how to handle this error with an exception (please ignore the real purpose of the functions, it's just to show the principle:
try
{
mHOQList[mCurrentFrame]->endOcclusionQuery();
} catch( Ogre::Exception& e )
{
if( e.getNumber() == Exception::ERR_RENDERINGAPI_ERROR
&& stdEx::string(e.getDescription()).beginsWith( "End occlusion called" ))
{
// a device lost occurred during our occlusion query. Simply ignore it.
return true;
}
else
throw;
}
We are doing an occlusion query here, which we know can not continue when a "device lost" event happens during it's operation. So we place it in a try/catch clause. When everything works out good in the endOcclusionQuery(), the catch() is never called, and everything is fine.
If an exception is thrown, we first check if we can handle it. We check the number of the exception and its description. If these informations have a specific value, we know that it's a benign error, we can safely ignore it and carry on the next frame. If we don't know how to handle it, we simply throw;, which leaves the handling of the exceplion to a catch() lower in the call hierarchy, which brings me to the next points:
They can be evaluated selectively.
The example above will catch and handle exceptions of the type Ogre::Exception, but nothing else. A std::exception or another exception type is not caught. Let's say for example the endOcclusionQuery() calls a callback in our own code, which then also gets into an exceptional state and throws. We would let this exception pass by and leave it to the lower (or higher) levels of the call hierarchy to handle it.
They can be rethrown.
In the example, we use throw; to re-throw and pass the handling to lower levels in the call hierarchy.
They can be stored and even re-thrown in a separate thread
Imagine a library with hundreds of worker threads, and a manager thread which coordinates these threads. Since exceptions are bound to a single thread, so the manager thread can never catch exceptions from the worker threads. But the worker threads can catch their own exceptions and either handle them if possible or store them, pass them to the manager thread, where it can be rethrown and be handled by the manager thread.
They can be thrown in Constructors
Constructors have no return value, and so it is impossible to check its success with return values. State members are possible, but awkward - they tend to be overlooked. So the preferrable way to deal with errors in a constructor is to throw (of course as a documented behavior). See also Throwing exceptions from constructors
They are standardized
Well when it comes to this, the example above is not the best. Ogre is a pretty old engine, long before C++11, and so the exception classes are proprietary. You can throw anything - from a char to a class LiverSausage. But today this shouldn't be done anymore - std::exception is the class of choice. It contains everything which is needed for a simple exception, and can be inherited for more sophisticated exceptions. It is commonly used and inherited in the STL, and there are helpers classes and functions like std::exception_ptr, std::current_exception() etc.
They can be used as a safe bailout for an unrecoverable program error. At the end, something ugly like this unfortunately can happen in the best programs. You can throw this fatal exception anywhere in your program, and you can catch this exception at a single place, where you can log the error, evaluate where it came from, perhaps even write a dump - so you have at least a clue what could have happened, which is at least less worse than simply crashing ;)
throw isn't used to return any value , it is used to throw exceptions i.e. if you think that a certain condition in the program is going to cause a runtime error or malfunction then you throw a exception which helps to avoid and deal with such runtime errors. Return is used to return from a function and a value to the calling function.
While this might sound bad, I actually let performance be a strong factor in guiding this decision. Most modern optimizers implement what's called zero-cost exception-handling, which ultimately translates to something like, "branch-free normal execution paths, but expensive exceptional paths".
It makes throwing quite expensive in exchange for making your normal execution paths really cheap. I don't have precise numbers for the costs but it's probably relatively extremely expensive if you're using a try/catch block just to test if a key exists in a data structure, e.g.
The other guiding force that I've found useful is the idea of an external exception outside of the programmer's control. Examples of that might be a client failing to connect to a server which should be up after repeated attempts, encountering a corrupt file, failing to allocate memory, things of this sort.
I did get into a debate one time with a colleague about whether a user jamming an abort button on a progress bar qualifies as an exceptional circumstance. I really thought it did because the operation is normally supposed to succeed, and a user aborting is a truly exceptional circumstance outside of the developer's control. On top of that it really simplified the code quite a bit over trying to propagate an abort status down the entire call stack.
In these cases where people might not agree about what is and isn't exceptional control flow, I use performance as like the deciding factor. Here throwing to abort an expensive operation isn't a big performance overhead, since it's not like we're throwing a million times in a critical loop. We're just throwing one time to abort a very expensive operation, and there the overhead of throwing becomes quite trivialized. So that's what I mean when I talk about performance being a deciding factor.
What are the places we should use the assert() function specifically? If it's a situation like determining if an integer value is greater than zero or a pointer is null, we can simply use a private function to check this. In this kind of situation, where should we use assert() over a custom written check?
Context: I write server software for a living, the kind that stays up for weeks before the next version is loaded. So my answers may be biaised toward highly defensive code.
The principle.
Before we delve into the specifics of where to use assert, it's important to understand the principle behind it.
assert is an essential tool in Defensive Programming. It helps validating assumptions (assert them actually) and thus catch programming errors (to be distinguished from user errors). The goal of assert is to detect erroneous situations, from which recovery is generally not immediately possible.
Example:
char const* strstr(char const* haystack, char const* needle) {
assert(haystack); assert(needle);
// ...
}
Alternatives.
In C ? There is little alternative. Unless your function has been designed to be able to pass an error code or return a sentinel value, and this is duly documented.
In C++, exceptions are a perfectly acceptable alternative. However, an assert can help produce a memory dump so that you can see exactly what state the program is in at the moment the erroneous situation is detected (which helps debugging), while an exception will unwind the stack and thus lose the context (oups...).
Also, an exception might (unfortunately) get caught by a high level handler (or an unsavory catch from a fellow developer (you would not do that, of course)), in which case you could miss completely the error until it's too late.
Where NOT to use it.
First, it should be understood that assert is only ever useful in Debug code. In Release, NDEBUG is defined and no code is generated. As a corollary, in Release assert has the same worth as a comment.
Never use it for checks that are necessary to the good behavior of the software. Error conditions should be checked and dealt with. Always.
Second, it should be understood that malformed input is part of your life. Would you want your compiler display an assert message each time you make an error ? Hum! Therefore:
Never use it for input data validation. Input data should be validated and errors appropriately reported to the user. Always.
Third, it should be understood that crashes are not appreciated. It is expected of your program that it will run smoothly. Therefore, one should not get tempted to leave asserts on in Release mode: Release code ends up in the end user hands and should never crash, ever. At worst, it should shutdown while displaying an error message. It is expected that no user data is lost during this process, and even better if upon restarting the user is taken back to where she was: that is what modern browsers do, for example.
Never leave asserts on in Release.
Note: for server code, upon "hitting" an assertion, we manage to get back in position for treating the next query in most cases.
Where to use it.
assert is on in Debug mode, and so should be used for Debugging. Whenever you test new code, whenever your test suite run, whenever software is in your (or your teammates) hands, whenever software is in you QA department hands. Asserts let you spot errors and gives you the full context of the error so that you can repair.
Use it during the development and testing cycles.
Even better. Since you know code will not be executed in Release you can afford to perform expensive checks.
Note: you should also test the Release binary, if only to check the performance.
And in Release ?
Well, in the codebase I work on, we replace the inexpensive asserts (the others are ignored) by specific exceptions that are only caught by a high level handler that will log the issue (with backtrace), return a pre-encoded error response and resume the service. The development team is notified automatically.
In software that is deployed, the best practices I have seen imply to create a memory dump and stream it back to the developers for analysis while attempting not to lose any user data and behave as courteously as possible toward the unfortunate user. I feel really blessed to be working server-side when I contemplate the difficulty of this task ;)
I'm gonna throw out my view of assert(). I can find what assert() does elsewhere, but stackoverflow provides a good forum for suggestions on how and when to use it.
Both assert and static_assert serve similar functions. Let's say you have some function foo. For example, lets say you have a function foo(void*) that assumes its argument is not null:
void foo(void* p) {
assert(p);
...
}
Your function has a couple people that care about it.
First, the developer who calls your function. He might just look at your documentation and maybe he will miss the part about not allowing a null pointer as the argument. He may not ever read the code for the function, but when he runs it in debug mode the assert may catch his inappropriate usage of your function (especially if his test cases are good).
Second (and more important), is the developer who reads your code. To him, your assert says that after this line, p is not null. This is something that is sometimes overlooked, but I believe is the most useful feature of the assert macro. It documents and enforces conditions.
You should use asserts to encode this information whenever it is practical. I like to think of it as saying "at this point in the code, this is true" (and it says this in a way so much stronger than a comment would). Of course, if such a statement doesn't actually convey much/any information then it isn't needed.
I think there's a simple and powerful point to be made:
assert () is for checking internal consistency.
Use it to check preconditions, postconditions, and invariants.
When there may be inconsistency due to external factors, circumstances which the code can't control locally, then throw an exception. Exceptions are for when postconditions cannot be satisfied given the preconditions. Good examples:
new int is ok up to its preconditions, so if memory is unavailable, throwing is the only reasonable response. (The postcondition of malloc is "a valid pointer or NULL")
The postcondition of a constructor is the existence of an object whose invariants are established. If it can't construct a valid state, throwing is the only reasonable response.
assert should not be used for the above. By contrast,
void sort (int * begin, int * end) {
// assert (begin <= end); // OPTIONAL precondition, possibly want to throw
for (int * i = begin, i < end; ++i) {
assert (is_sorted (begin, i)); // invariant
// insert *i into sorted position ...
}
}
Checking is_sorted is checking that the algorithm is behaving correctly given its preconditions. An exception is not a reasonable response.
To cut a long story short: assert is for things which WILL NEVER happen IF the program is LOCALLY correct, exceptions are for things which can go wrong even when the code is correct.
Whether or not invalid inputs trigger exceptions or not is a matter of style.
You usually use it when you want the program to abort and display a runtime error if a boolean condition is not true. It is usually used like this:
void my_func( char* str )
{
assert ( str != NULL );
/* code */
}
It can also be used with functions that return a NULL pointer on failure:
SDL_Surface* screen = SDL_SetVideoMode( 640, 480, 16, SDL_HWSURFACE );
assert ( screen != NULL );
The exact error message assert() gives, depends on you compiler but it usually goes along these lines:
Assertion failed: str, mysrc.c, line 5
As a C programmer, I don't have much experience with exceptions. I'm rather used to errno as a means of communicating errors across several function calls. That having said, I don't see the distinguishing feature of exceptions, so...
What is the fundamental difference between exceptions and using errno?
There are so many differences here it's hard to say where to start.
First of all, errno as used in C is a global variable; this means every routine that calls an errno-setting subroutine must check errno before performing any other work, if it cares about correctness. Luckily enough, errno is threadsafe.
C++ exceptions automatically unwind up the call stack until they find a function prepared to handle the fault. This means that in most cases users don't have to explicitly check every call for an error; instead they can collect error returns in one place. C++ exceptions can contain values other than integers, unlike errno.
You can casually ignore errno. Exceptions must be dealt with.
Of course I've seen my share of:
try {
// something
}
catch( ... ) {
// nothing
}
// continue as if nothing happened
and (Java)
try {
// something
}
catch( Throwable t ) {
// nothing
}
// continue as if nothing happened
BUT at least that kinda jumps out at you when you're plowing through someone else's mess.
I feel compelled to point out that writing correct programs in the face of exceptions is not easy. You do well to do some research on the subject, perhaps starting with Guru of the Week. Just look for the word exception.
1) Exceptions can be anything, not just an integer. So the data communicated is different.
2) Exceptions do non-local control flow, so you don't have to check at every level in the way that in practice with errno, you also return a value that indicates error and every caller checks for errors and bails out early if one has occurred. Conversely, error returns do local control flow, so you can always see exactly when errors are propagated through a given piece of code. This difference radically changes coding style. So the means of communicating are different too.
To me, the most important difference is that errno is easily ignored, whereas exceptions are pretty hard to ignore - the program will terminate if you end up ignoring them... Plus, exceptions are (well, should be) objects, so you can carry more useful information.
The other, very important difference is that exceptions can easily be handled at the point where the software can actually make an informed decision how to handle the problem, which is usually several levels up the call stack. That's not that easy to do with error codes.
One pattern which I've found useful on embedded systems is to have an error flag for each stream, but provide that an I/O operation which is attempted when the flag is set will fail immediately. Thus, code can do something like:
pkt_type = tcp_getbyte(my_stream, timeout);
pkt_length = tcp_getbyte(my_stream, timeout);
pkt_length |= tcp_getbyte(my_stream, timeout) << 8;
if (pkt_length < MAX_PACKET_LENGTH)
{
for (i=0; i<pkt_length; i++)
buffer[i] = tcp_getbyte(my_stream, timeout);
}
if (!my_stream->error)
{
/* Do something with packet */
}
If one attempt to get a byte times out, succeeding attempts will fail unconditionally, returning zero. It's not necessary to check every operation for failure; if something goes wrong, the system will end up behaving roughly as though tcp_getbyte() had thrown an exception, just not quite as fast.
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
design by contract tests by assert or by exception?
What is the preferred way to handle a null pointer passed in as an output argument to a function? I could ASSERT but I feel like its not good to let a library crash the program. Instead, I was thinking about using exceptions.
Throw an exception! That's what they're for. Then the user of your library can decide if they want to handle it gracefully or crash and burn.
Another specific solution is to return an invalid value of a valid type, such as a negative integer for a method returning an index, but you can only use that in specific cases.
I would use an assertion if null pointers are not allowed. If you throw an exception for null pointers, you effectively allow them as arguments, because you specify behavior for such arguments. If you don't allow null pointers but you still get them, then some code around definitely has a bug. So in my opinion it does not make sense to "handle" it at some higher levels.
Either you want to allow callers to pass null pointers and handle this case by throwing an exception and let the caller react properly (or let the exception propagate, as the caller wishes), or you don't allow null pointers and assert them, possibly crashing in release mode (undefined behavior) or use a designated assertion macro that is still active in release mode. The latter philosophy is taken by functions such as strlen, while the former philosophy is taken by functions such as vector<>::at. The latter function explicitly dictates the behavior for out-of-bound values, while the former simply declares behavior undefined for a null pointer being passed.
In the end, how would you "handle" null pointers anyway?
try {
process(data);
} catch(NullPointerException &e) {
process(getNonNullData());
}
That's plain ugly, in my opinion. If you assert in the function that pointers are null, such code becomes
if(!data) {
process(getNonNullData());
} else {
process(data);
}
I think this is far superior, as it doesn't use exceptions for control flow (supplying a non-NULL source as argument). If you don't handle the exception, then you could aswell fail already with an assertion in process, which will directly point you to the file and line number the crash occurred at (and with a debugger, you can actually get a stack trace).
In my applications, i always take the assert route. My philosophy is that null pointer arguments should be handled completely by non-exceptional paths, or asserted to be non-NULL.
Do both.
Any that can be caught during development will abort the process which will make it obvious to the developer that they need to fix it.
And if one does make it past testing, there's still the exception that a robust program can handle.
And this is easy enough to put into a macro (must be a macro and not an inline so that assert properly reports the line number - thanks to #RogerPate for pointing out this out):
#define require_not_null(ptr) \
do { assert(ptr); if (!(ptr)) throw std::logic_error("null ptr"); } while (0)
If you value performance, assertions will be off in release. They're there to catch problems that should never happen, and shouldn't be used to catch stuff that may happen in real life. That's what exceptions are for.
But let's back up a second. Where is it guaranteed what will happen if you dereference a null pointer, whether writing to it or not? It may crash for you, but it won't crash in every OS, or every compiler, or any anything else. That it crashes for you is just good fortune on your part.
I'd say throw an exception if you're not gonna create the object yourself and have the pointer to the pointer passed to you, the way I often see 'out' params passed.
If you are programming the autopilot system for the ultimate airplane, I should recommend trying to handle the exception gracefully.
Please read the Eiffel specifications for "contract programming" (a very nice language indeed) and you'll be enlightened. NEVER crash if you can handle the event.
if you throw, a client can decide to re-throw, or not handle the exception, or crash or call exit or try to recover or....
If you crash, the client crashes with you.
So throw, to give your client more flexibility.
I would neither raise an exception nor use assert, which is what the C++ Standard library does. Consider about the simplest function in the library, strlen(). If it raised an exception, how would you possibly handle it? And the assertions won't fire in production code. The only sensible thing to do is say explicitly that the function must not be called with a NULL pointer as a parameter, and that doing so will result in undefined behaviour.
The benefit of using exceptions is that you let your client code decide how to handle the exceptional circumstance. That's for the case where the parameter being non-null is a stated precondition of the function. For functions taking optional out parameters, though, passing NULL can be an indication that the client is not interested in the value. Presumably, you're using the return value to signify success or failure, and if that's the case, you could simply detect the NULL and return an error code if the parameter is mandatory, or simply ignore it if the parameter is optional. This avoids the overhead of exceptions and still allows error handling on the client's part.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
design by contract tests by assert or by exception?
Is there a rule of thumb to follow when deciding to use exceptions instead of asserts (or vice versa). Right now I do only throw if it's something I think will happen during runtime on the user side (like a socket or file error). Almost everything else I use asserts.
Also, if I were to throw an assert, what is a nice standard object to throw? If I recall correctly there is std::logic_error, but is that not a good object to throw? What would I throw for a missing file or unexpected input (such as from the command line instead of a frontend app)?
My rule of thumb:
Exceptions are used for run-time error conditions (IO errors, out of memory, can't get a database connection, etc.).
Assertions are used for coding errors (this method doesn't accept nulls, and the developer passed one anyway).
For libraries with public classes, throw exceptions on the public methods (because it makes sense to do so). Assertions are used to catch YOUR mistakes, not theirs.
EDIT: This may not be entirely clear, due to the null value example. My point is that you use assertions (as others have pointed out) for conditions that should NEVER happen, for conditions that should NEVER make it into production code. These conditions absolutely must fail during unit testing or QA testing.
Assert the stuff that you know cannot happen (i.e. if it happens, it's your fault for being incompetent).
Raise exceptional situations which are not treated by the regular control flow of the program.
You use exceptions for exceptional situations. For example an out of memory situation or a network failure.
You use assert to ascertain that a cetain precondition is met. For example a pointer is not NULL or an integer is within a certain range.
I use asserts for things that should never happen, yet do. The sort of thing that when it happens, the developer needs to revisit incorrect assumptions.
I use exceptions for everything else.
In reusable code, I prefer an exception because it gives the caller a choice of handling or not handling the problem. Just try catching and handling an assert!
Assert is a means to verify that the program is in a possible state. If a function returns -1 when it should only return positive integers, and you have an assert that verifies that, your program should stop because it puts your program in a dangerous state.
As a general rule, I throw exceptions from:
public functions of a package to catch programming errors.
internal functions to report system errors or pass-through sub-system errors.
where I use asserts only internally to catch implementation mistakes.