Assertion vs Exception Handling

P

peter koch

Euh, maybe my reading skill are poor but:

Quote from Ian Collins in this thread:

"My basic guideline is that a catch should always re-throw, because if
your program can recover from the situation, then it isn't an error."

"Exceptions are for errors, that's what they were designed for. If your
program can handle some particular condition an error? The answer is,
it isn't."  
[snip]

I believe that quote is from Daniel T. I can't imagine Ian Collins
claiming that.

/Peter
 
P

peter koch

Correction: "who say that asserts should always be enabled". :)

But always enabling assertions is a good idea. I see no reason
whatsoever to turn assertions off unless you have a piece of code that
gets to slow when enabling the assertions.
Personally, I used to have more levels of assertions. Asserts that
make O(1) algorithms O(n) (or worse) were disabled in release-code
(and often also in test-code: it was typically only enabled after
changing code that might affect the module), but normal asserts were
normally allowed to stay unless a performance test told us not to.

/Peter
 
I

Ian Collins

Euh, maybe my reading skill are poor but:

Quote from Ian Collins in this thread:

"My basic guideline is that a catch should always re-throw, because if
your program can recover from the situation, then it isn't an error."

"Exceptions are for errors, that's what they were designed for. If your
program can handle some particular condition an error? The answer is,
it isn't."
[snip]

I believe that quote is from Daniel T. I can't imagine Ian Collins
claiming that.

Thanks! Yes, the quote was form Daniel T and not me.
 
J

James Kanze

"Ian Collins" <[email protected]> wrote in message

[...]
Actually I think embedded software is one of the exceptions
where a higher degree of defensiveness is required (especially
where safety is a concern) and a reboot is usually the best
outcome for unexpected state. On the other hand I have worked
in the mobile phone industry and from what I can recall we
didn't use release mode asserts much.

I think it depends on where your program is situated. If it's
in the phone itself, I can see not using asserts much, except
maybe in a very few of the critical parts. A mobile phone,
today, is pretty much the same thing as a games console:). But
the software I've seen on the server side definitely makes
extensive use of asserts; if anything goes wrong, you want to
fail brutally, so that the backup systems can detect the failure
and take over.
 
J

James Kanze

"James Kanze" <[email protected]> wrote in message

[...]
You are confusing crashes (faults) with assertion failures:
they are not the same thing. To change the behaviour of
assert use _set_error_mode not SetErrorMode.

I didn't know about that one. Still, catching SIGABRT does seem
to have worked, at least in this one particular case.
(According to the standard, an assertion failure is required to
result in a SIGABRT signal. On a lot of systems, signals are
also what is used to indicate other types of crashes: segment
violations and such.)
 
J

James Kanze

On 03/14/10 12:40 PM, James Kanze wrote:
Isn't that what I said?

I think we pretty much agree on this issue. But I don't see
anything "nebulous" about release mode. And it's the same mode
I use when I test my code, because I don't believe in releasing
untested code. (Something I'm pretty sure you agree with as
well.)
 
I

Ian Collins

[...]
Actually I think embedded software is one of the exceptions
where a higher degree of defensiveness is required (especially
where safety is a concern) and a reboot is usually the best
outcome for unexpected state. On the other hand I have worked
in the mobile phone industry and from what I can recall we
didn't use release mode asserts much.

I think it depends on where your program is situated. If it's
in the phone itself, I can see not using asserts much, except
maybe in a very few of the critical parts. A mobile phone,
today, is pretty much the same thing as a games console:). But
the software I've seen on the server side definitely makes
extensive use of asserts; if anything goes wrong, you want to
fail brutally, so that the backup systems can detect the failure
and take over.

My example was from the infrastructure side of mobile (or fixed line)
networks. The device in question can shut down and exchange or base
station, so it must "fail brutally" if an inconsistent state is detected.
 
J

James Kanze

Did I say otherwise?

No. You didn't mention testing (although I know you're a firm
believer in it).

With regards to the core dump, there are some systems you can't
get it on. But an assertion failure will still occur closer to
the point of failure, and the error message will generally give
you some indication as to what when wrong.
 
I

Ian Collins

I think we pretty much agree on this issue. But I don't see
anything "nebulous" about release mode. And it's the same mode
I use when I test my code, because I don't believe in releasing
untested code. (Something I'm pretty sure you agree with as
well.)

I do. By "a nebulous concept" I mean there isn't a standard definition
for release mode. Windows developers often use the term to
differentiate between VC++'s Debug and Release modes. Unix and embedded
developers tend not to use it at all!
 
J

James Kanze

And thus spake James Kanze <[email protected]>
Sat, 13 Mar 2010 15:23:19 -0800 (PST):
Well, you do live in a very interestingly limited world it
seems.

Very limited, yes. Limited to five or six different compilers,
on as many different systems.
And labeling more or less everyone who does not agree with you
as unprofessional is quite an interesting statement as well.

There's such a thing as professional ontology.
At my company, we _do_ have two different builds, one for
debugging and one for release. The application is very
performance-sensitive. In the debugging version, all sorts of
sanity checks and asserts are active, which slow the code down
by an additional factor of 5-10 (apart from the lack of
optimisation), but which help to make sure that the geometry
core is in fact doing something mathematically sane.

There are certainly cases where it's justified. Just as there
are cases where three or more modes are justified: if some
checks mean that it takes two hours, instead of ten minutes, to
get the the error location, then you have a build which turns
those checks off, and only those checks.
Apart from that, asserts do not always make sense in non-debug
code anyway. For example, I currently also develop a graphics
transformation library. If I build it with fully optimisation,
it becomes faster by a factor of 10-20 (among other things due
to massive inlining). However, it is more or less _impossible_
to debug when built fully optimised, so active asserts would
not do much good anyway.
By the way, the standard 'assert' macro defined in the
standard IIRC is explicitely disabled if 'NDEBUG' is defined,
and setting this preprocessor symbol also disables all sorts
of range checks etc.

It shouldn't. Typically, in the compilers I've used (including
VC++), there have been any number of different options
controlling different aspects of checking.
in STL containers at least in VC++, if I am not mistaken.

Debugging in STL containers in VC++ is definitely separate from
NDEBUG, since in most of our build configurations, we have
asserts turned on, but most of the checks in the STL turned off.
So in my opinion it could in fact be quite common that asserts
are inactive in production code, at least if it is
performance-critical code built with full optimisation.

That's a big if. Even today, most (not all) programs are IO
bound, and are delivered without optimization, because compiler
optimizations don't speed up disk.
 
J

James Kanze

How's that that C and C++ folks always worry about
performance, while Java folks don;t worry? All my apps run
with debug builds and asserts and are lot faster then Java
apps. If you got the point ;)

:)

Most C++ folks don't worry that much about performance. Or
rather, they only worry about it in the few places where it
counts. And judging from the many companies I've worked with,
it's extremely rare to ship code compiled with optimization
turned on or asserts turned off.

(Of course, there are times when speed is critical, and in such
cases, you do what you have to do.)
 
J

James Kanze

"Ian Collins"<[email protected]> wrote in message
[...]
Actually I think embedded software is one of the exceptions
where a higher degree of defensiveness is required
(especially where safety is a concern) and a reboot is
usually the best outcome for unexpected state. On the
other hand I have worked in the mobile phone industry and
from what I can recall we didn't use release mode asserts
much.
I think it depends on where your program is situated. If
it's in the phone itself, I can see not using asserts much,
except maybe in a very few of the critical parts. A mobile
phone, today, is pretty much the same thing as a games
console:). But the software I've seen on the server side
definitely makes extensive use of asserts; if anything goes
wrong, you want to fail brutally, so that the backup systems
can detect the failure and take over.
My example was from the infrastructure side of mobile (or
fixed line) networks. The device in question can shut down
and exchange or base station, so it must "fail brutally" if an
inconsistent state is detected.

That's been my experience as well (and telecoms is doubtlessly
the domain where I have the most experience). But I must be
getting confused with the attributions; I didn't think it was
you who said "On the other hand I have worked in the mobile
phone industry and from what I can recall we didn't use release
mode asserts much", which was the statement I was responding to.
 
I

Ian Collins

That's a big if. Even today, most (not all) programs are IO
bound, and are delivered without optimization, because compiler
optimizations don't speed up disk.

I don't see how you can justify that James, most programmes today
probably run on embedded platforms that don't have disks!
 
B

Brian Wood

:)

Most C++ folks don't worry that much about performance.  Or
rather, they only worry about it in the few places where it
counts.  And judging from the many companies I've worked with,
it's extremely rare to ship code compiled with optimization
turned on or asserts turned off.

(Of course, there are times when speed is critical, and in such
cases, you do what you have to do.)

Stroustrup's home page says:
"I tend to be quite concerned about run-time and space performance."
I'm not worried about performance, but for a number of reasons,
I'm interested in it. Most Americans didn't think much about
efficient transportation either for decades. That's been changing
with the price of gas going up and the economy being bad. With
budgets tight around the world, we're seeing a revival in
interest in efficient software. More companies are employing
cloud based approaches and are rethinking some of their past
decisions. Recently in this newsgroup we heard Facebook
admitting their PHP habit has some nasty consequences and
embracing C++ for cost/performance reasons. Most Java people
are lackadaisical about performance, though.

My motto is "every little bit helps." A number of people
have helped me learn that.


Brian Wood
http://webEbenezer.net
(651) 251-9384
 
N

Nick Keighley

Yes I know all about RAII but that doesn't stop std::terminate from being
called if exceptions are always re-thrown, something which I do not agree
with as a general guideline.

so there /is/ a difference between asserts and exceptions even when
the exception handlers always rethrow.
 
N

Nick Keighley

True, and my domain probably influences my definitions (as well it
should.) In my domain, (games and educational software for 8-12 y.o.
girls,) the design is such that the user *can't* give invalid input.
Also, we have specific resources that we *must* keep within (a failed
memory allocation for example means the code needs to be rewritten,) and
the only files that we open have to be there or the program must abort

that's the difficulty with trying to write general advice about this
stuff. Domains vary enormously. See the fights on "should we disable
asserts in the release version". Makes the Thirty Years War look like
playground stuff. The nice thing about throwing an exception is the
lower layer has put off the decision. Then the higher layers of
software can decide to abort, recover, retry, whatever.
 
A

Alf P. Steinbach

* Yannick Tremblay:
I'd agree that it is worthwhile to ship code with asserts.

However, I'd disagree that you should not turn on optimisation
shipping code. Compiler optimisation can make a huge difference and
very importantly, it allow the developers to write clear, safe and
maintainable code and let the compiler do it's job. Turning off
compiler optimisation incur the very big risk of programmers trying to
do the copmpiler job and start writing obfuscated code because they
think it will be more efficient.

AOL. Or, as they say nowadays, +1.

Cheers,

- Alf
 
N

Nick Keighley

I hate repeating myself but:

Using performance as a criterion on whether or not to use asserts make the
asserts completely arbitrary and pointless.

why? Potentially assert()s could be very expensive.

assert (is_tree_valid());
assert (is_result_prime());

I confess I'd probably siphon these off to separate test modules. But
I dodn't see why cheaper assert()s shouldn't remain. *And* they do
remain in my code.

 Like I said earlier you need to
be either extremely defensive or not defensive at all

and I think you're wrong. There is a cost/benefit function to look at.
If the cost is low and benefit reasonable then leave the test in. One
of the nice things about assert() is they are relativly cheap to put
in (cheap as in man-milliseconds cheap). If you don't like assert()
use a CHECK() macro instead.
and the degree of
defensiveness depends on the application domain.  
yes.


It is simpler to just
except the truth that "asserts are *mostly* a debugging tool".

that's opinion masquerading as truth.
 
M

Michael Doubez

I think you will find that a lot of C++ programmers do care about
performance, I do, games programmers certainly do, embedded programmers
probably do especially when the CPU is not all that fast.  It is woolly
thinking to release products with optimizations turned off due to some silly
sense of non-existent risk - put more trust in your compiler.

Debugging with the core of a non-optimized code is far easier: as an
example, optimized out values may hide the information you need.

At my current position, they are ready to pay for a 30% slower code
(it is a measured value) and, at the same time, they are concerned
with optimisation.
They prefer that rather than take the risk of spending hours trying to
figure out why a code crashed.

This tension leads to an interesting shift in the way of coding C++.
 
M

Michael Doubez

Agreed but the point is that, at some point, elements parts of the
program's logic leaks into the runtime mechanism.

And this mechanism now also catch and let pass bugs and inconsistent
state. And, as it should, it happened ... :)
However discarding bad data and associated objects is not the same as trying
to continue because of some bug in the code.  Bugs in code should result in
either an abort (due to an assert) or an exception which results in program
termination.

IIUC what you are advocating is to define something like the assert
macro but that throws and exception instead of halting the program and
keep assert() for debug mode.

Personally, I prefer putting the debug code in unit tests and
everything that is in the source code is release code. As to aborting
the program, I guess it might be a matter of taste but I prefer a
clean image of the state of the program at the point of failure (and
unwinding the stack on an unknown state is risky stuff).

The other alternative is to produce bug-free code :)
The correct answer to your problem is better data validation
and normal error handling

In this cases, data validation is not simply a validation: the whole
state of the part of the program is compromised. And I don't want to
explain to a trader why I ignored some piece of data the market sent.
(through use of exceptions perhaps).

Indeed, I now throw a std::logic_error (first time in my coder's
life).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,599
Members
45,169
Latest member
ArturoOlne
Top