views:

1700

answers:

7

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 its 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? IIRC there is std::logic_error but that is 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)?

+3  A: 

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.

Gamecat
The parallelism of "assert" and "ascertain" does not work. To "assert" is to declare positively, whereas "ascertain" is to learn. Thus, assert presupposes "true", whereas ascertain suggests no particular bias. It's not a terrible mnemonic, but the suggested etymology is flawed.
Argalatyr
Agree with Argalatyr. To assert is "to insist upon", "to declare boldly" or similar. To ascertain is "To discover with certainty, as through examination or experimentation", for which "discover" is a synonym.
Mike Hofer
Also, the "exceptions for exceptional situations" rule could use clarification. Why is a network failure exceptional but not a null pointer?
JW
+1  A: 

Assert is a mean 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.

Loki
+6  A: 

It's a duplicate: http://stackoverflow.com/questions/117171/design-by-contract-tests-by-assert-or-by-exception . You'll find good answers there. Can't come up with a nicer way to explain it than Dima in there.

Johannes Schaub - litb
+4  A: 

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.

+1 for the first half of this answer, but the second half doesn't help much.
JW
A: 

As a general rule, I throw exceptions from:

  1. public functions of a package to catch programming errors.
  2. internal functions to report system errors or pass-through sub-system errors.

where I use asserts only internally to catch implementation mistakes.

donpark
+1  A: 

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!

Paul Beckingham
+1  A: 

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.

Mike Hofer