C++ Assertions and Exceptions
C++ Assertions and Exceptions
Programming
Outline
What Are Assertions?
Four Purposes for Assertions
Types of Assertions
Assertion Example
Programming by Contract
Using Assertions to Specify ADTs
Handling Assertion Violations
Assertions in C
Assertions in C++ 1
What Are Assertions?
Assertions are boolean expressions that serve
to express the semantic properties of classes
and member functions.
2
Four Purposes for Assertions
Aid in constructing correct programs.
{ e.g., specify input preconditions and output
postconditions.
Documentation aid.
{ e.g., supports \programming by contract"
Debugging aid.
{ Find out where/when assumptions are wrong :::
3
Types of Assertions
Assertions are used for several purposes:
{ Preconditions
State the requirements under which subpro-
grams are applicable.
{ Postconditions
Properties guaranteed upon subprogram exit.
{ Class Invariants
Properties that characterize class instances
over their lifetime
Note, subprogram preconditions and post-
conditions are implicitly assumed to include
the class invariant.
{ Loop Invariants
Loop invariants specify properties that are
always true during the execution of a loop.
4
Assertion Example
-- Ei el array
class ARRAY[T] export
lower, upper, size, get, put
feature
lower, upper, size : INTEGER;
Create (minb, maxb : INTEGER) is do ::: end;
get (i : INTEGER): T is
require -- precondition
lower <= i; i <= upper;
do end;
:::
e.g.,
{ A precondition and a postcondition associated
with a subprogram describe a contract that
binds the subprogram.
But only if callers observe the precondition :::
6
Using Assertions to Specify ADTs
Conceptually, ADTs consist of four parts:
(1) types
(2) functions
(3) preconditions/postconditions
(4) axioms
However, most languages only allow speci cation
of the rst two parts (i.e., types and functions)
7
Handling Assertion Violations
If the client's part of the contract is not
ful lled (i.e., if the caller does not satisfy
the preconditions) then the class is not
bound by the postcondition.
This can be integrated with an exception
handling mechanism, e.g.,:
{ Exceptions are generated:
(1) when an assertion is violated at run-time
(2) when the hardware or operating system
signals an abnormal condition.
{ Note, exceptions should not be used as non-
local gotos.
They are a mechanism for dealing with ab-
normal conditions by either:
(1) Termination: cleaning up the environment and repo
the caller,
(2) Resumption: attempting to achieve the aim of the o
8
Assertions in C
Enabled by including the <assert.h> header.
f
char *callers bu er;
char bu er[100];
/* */:::
10
Assertions in C (cont'd)
Another interesting application of assert
is to extend it to perform other duties as
well.
{ e.g., code pro ling and error logging:
#de ne assert(x) f \
static int once only = 0; \
if (0 == once only) f \
once only = 1; \
pro le assert (" LINE ", " FILE "); \
g\
/* */ \
:::
11
Assertions in C++
The overall purpose of the proposed ANSI-
C++ assertion implementation is twofold:
1. To provide a default behavior similar to the C
assert facility.
12
Assertions in C++ (cont'd)
What follows is the proposed implemen-
tation:
// -- le assert.h --
#ifndef ASSERT H
#de ne ASSERT H
#ifndef NDEBUG
#include <iostream.h>
extern "C" void abort (void);
// -- generic implementation
template <class E> class assert f
public:
assert (int expr, const char *exp,
const char* le, int line) f
if (!expr) throw E (exp, le, line);
g
assert (void *ptr, const char *exp,
const char* le, int line) f
if (!ptr) throw E (exp, le, line);
g
g;
13
Assertions in C++ (cont'd)
Proposed implementation (cont'd)
// -- speci c C++ macro (needed for preprocessing!)
#de ne Assert (expr, excep) \
( assert<excep> (expr, #expr, \
FILE , LINE ))
// -- standard exception
class Bad Assertion f
public:
Bad Assertion (const char *exp,
const char* le, int line) f
cerr << "Assertion failed: " << exp
<< ", le " << le
<< ", line " << line << 'n';
abort ();
g
g;
// -- C-like macro
#de ne assert(expr) (Assert (expr, Bad Assertion))
#else /* !NDEBUG */
#de ne Assert (expr, excep) (0)
#de ne assert (expr) (0)
#endif /* NDEBUG */
#endif /* ASSERT H */
14
Assertions in C++
The C++ assert Macro
{ As with the C macro, the C++ assert macro
is intended to be used as the irrevocable de-
tection of a program failure.
{ A trivial example is null pointer testing, as in:
class String f
// :::
public:
String (const char* p) f
assert (p != 0); // C++ macro
/* Aborts if p == 0 */
:::
g
g;
{ Validity of the expression is checked and a rudi-
mentary message is printed in case of failure.
15
Assertions in C++ (cont'd)
The C++ Assert Macro
{ The primary goal of the Assert macro is to
delegate the responsibility for handling the fail-
ure to the caller.
e.g., print appropriate error messages, make
a call to exit instead of abort :::
17
Assertions in C++ (cont'd)
The Assert Macro (cont'd)
{ Since the exception is thrown before the pro-
gram failure occurs (e.g., Out Of Range), the
environment is not corrupted when the run-
time ow returns to the caller.
{ If an exception is not caught (as is the case for
the Checked Vector::Out Of Range above), a
call to terminate is performed.
The default behavior of terminate is to call
abort.
{ An uncaught exception resulting from a call
to Assert will thus unwind the stack, unlike a
call to assert. Calls to local destructors will be
performed.
Note, this can alter the conditions under
which the failure occurred.
18