By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
445,897 Members | 1,969 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 445,897 IT Pros & Developers. It's quick & easy.

Assert vs. exceptions

P: n/a
When should one prefer assert-ing to throwing an exception?

Jul 23 '05 #1
Share this Question
Share on Google+
11 Replies


P: n/a
BigMan wrote:

When should one prefer assert-ing to throwing an exception?


assert-ing is a debug-build only tool. They are not present in
release-builds, that is the program as usually shiped to the
customer.

--
Karl Heinz Buchegger
kb******@gascad.at
Jul 23 '05 #2

P: n/a
On 13 Apr 2005 01:10:42 -0700, BigMan <Bi****@abv.bg> wrote:
When should one prefer assert-ing to throwing an exception?


assertions should protect from (not always obvious) mistakes of the
developer, e.g. using a pointer despite its being NULL.

exceptions are a way to handle errors that may legitimately occur at
runtime, e.g. the failure of trying to connect to some server (which may
not respond for various reasons).

Jul 23 '05 #3

P: n/a
BigMan wrote:
When should one prefer assert-ing to throwing an exception?


Always assert, unless you have no other choice, but even then consider
the exception to be a design flaw to be eliminated.

Jul 23 '05 #4

P: n/a
BigMan wrote:
When should one prefer assert-ing to throwing an exception?


The latter spanks the user. The former spanks the programmer.

--
Phlip
http://industrialxp.org/community/bi...UserInterfaces
Jul 23 '05 #5

P: n/a
BigMan wrote:
When should one prefer assert-ing to throwing an exception?


The assert macro is used to help programmers detect bugs
and *not* exceptions.

An exception is an unpredictable but expected event
which cannot be prevented and must be handled.
Exceptions should be handled to the extent possible
at the point where they are first detected.
If the exception cannot be handled completely
in the function where it is first detected,
all of the information required to handle the exception
in the calling program should be encoded in an exception object
and that object should be passed back to the calling program
as a return value by "throwing an exception".

Programming errors (bugs) are *not* exceptions.
Bugs are unexpected events which, once detected,
are always predicable and preventable by fixing the bug.
You can't "handle" bugs except by fixing them.
Once you have found and fixed all of the bugs,
the assert macros are no longer necessary
and you should turn them off by defining the NDEBUG macro.

Allowing assertions to persist in distributed software
only means that you haven't finished testing and debugging.
This is sometimes acceptable in alpha and beta distributions
but very unprofessional otherwise.
Jul 23 '05 #6

P: n/a
My experience shows that if the caller of a library function must take
further actions based on the return value (e.g. in a switch statement),
they should watch out for unexpected return values (usually one puts a
default clause to catch such cases). So, should I assert( false); in
the default clause or should I throw an exception there?
And what about the case where the same developer implements the caller
and the callee in the same source file?

Jul 23 '05 #7

P: n/a
BigMan wrote:
My experience shows that if the caller of a library function must take
further actions based on the return value (e.g. in a switch statement),
they should watch out for unexpected return values (usually one puts a
default clause to catch such cases). So, should I assert( false); in
the default clause or should I throw an exception there?
Whose fault is the error? You describe a programmer not implementing all
possibilities in a switch. That's an assertion.

However, if a long list of return values might be the user's fault, throw an
exception. For example, if you disconnect your 'net connection, the sockets
library could return any number of time-outs, dropped signals, etc.
Translate them into a string and stick them into the user's face.

Also, write all your code exception-safe and exception-neutral. You should
generally roll state back to the point of the last program input.
And what about the case where the same developer implements the caller
and the callee in the same source file?


Not relevant - the biggest distinction is whether the fault is the user's or
the programmer's. For example, users should not disconnect their 'net
connections while browsing. (Your ISP is also a user;)

--
Phlip
http://industrialxp.org/community/bi...UserInterfaces
Jul 23 '05 #8

P: n/a


BigMan wrote:
My experience shows that if the caller of a library function must take
further actions based on the return value (e.g. in a switch statement),
they should watch out for unexpected return values (usually one puts a
default clause to catch such cases). So, should I assert( false); in
the default clause or should I throw an exception there?
And what about the case where the same developer implements the caller
and the callee in the same source file?


Here we have a simple rule on who gets to fix a bug.

"The person with responsibilty for the code that supplied the
input that asserted gets to fix the code."

after 15 years of this policy it is typical to find in our methods more
asserions than live code.

In your example of a switch most of our default statements will
ASSERT_MISSING_CASE.

Jul 23 '05 #9

P: n/a
lilburne wrote:
Here we have a simple rule on who gets to fix a bug.

"The person with responsibilty for the code that supplied the
input that asserted gets to fix the code."

after 15 years of this policy it is typical to find in our methods more
asserions than live code.


That is such a good rule that I should not go extreme on you.

However, some people claim a team should pair program, rotate pairs
frequently, own tasks not code, and work on any code in the system to finish
a task. Shared code ownership leads to elegant code that looks like it was
written by a single, very intellegent, individual. However, the team might
honestly not know who wrote what code.

They also claim this policy leads to a very low defect rate, and a very high
test/code ratio.

--
Phlip
http://industrialxp.org/community/bi...UserInterfaces
Jul 23 '05 #10

P: n/a
Phlip wrote:
lilburne wrote:

Here we have a simple rule on who gets to fix a bug.

"The person with responsibilty for the code that supplied the
input that asserted gets to fix the code."

after 15 years of this policy it is typical to find in our methods more
asserions than live code.

That is such a good rule that I should not go extreme on you.

However, some people claim a team should pair program, rotate pairs
frequently, own tasks not code, and work on any code in the system to finish
a task. Shared code ownership leads to elegant code that looks like it was
written by a single, very intellegent, individual. However, the team might
honestly not know who wrote what code.

We don't normally pair program and although we don't really have code
ownership it is sometimes difficult to avoid. You really don't want
anyone messing with the innards of a continuous 5 axis machining
algorithm. Each change to a function is documented, with references back
to the originating requirement, or bug report, log of test results,
design discussions, proposed change discussions. Additionally any
modification or creation of a document, bug report, or enhancement
request, gets automatically mailed to every team member, or indeed
anyone in the company that expresses an interest.

Jul 23 '05 #11

P: n/a
BigMan wrote:
My experience shows that,
if the caller of a library function must take further actions
based on the return value (e.g. in a switch statement),
they should watch out for unexpected return values
(usually one puts a default clause to catch such cases).
So, should I assert(false); in the default clause?
No!
The default clause should be used to handle exceptions.
Or should I throw an exception there?
You must try to handle the exception in the default clause.
If you can't handle the exception completely
in the context of the function then you should
create an exception object that contains all of the information
required to handle the exception in the calling program
and return or throw that exception.
And what about the case
where the same developer implements the caller and the callee
in the same source file?
What about it?

cat main.cc #include <iostream>
#include <cstdlib>
#include <cassert>

int f(void) {
return rand()%9 + 1;
}

int main(int argc, char* argv[]) {
srand((1 < argc)? atoi(argv[1]): 0);
int i = f();
assert(0 < i);
switch(i) {
case 1:
std::cout << "first" << std::endl;
break;
case 2:
std::cout << "second" << std::endl;
break;
case 3:
std::cout << "third" << std::endl;
break;
default:
std::cout << "Sorry! You lose." << std::endl;
}
return 0;
}
g++ -Wall -ansi -pedantic -o main main.cc
./main

second
Jul 23 '05 #12

This discussion thread is closed

Replies have been disabled for this discussion.