0% found this document useful (0 votes)
20 views

C++ Assertions and Exceptions

This document discusses assertions and their uses in object-oriented design and programming. Assertions are boolean expressions that express semantic properties of classes and functions. They serve four main purposes: aiding in constructing correct programs, providing documentation, enabling debugging, and serving as the basis for an exception mechanism. The document outlines assertion types like preconditions, postconditions, and class invariants. It provides examples of assertions in C++ and how they support the concept of "programming by contract".

Uploaded by

Esmo Immo
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
20 views

C++ Assertions and Exceptions

This document discusses assertions and their uses in object-oriented design and programming. Assertions are boolean expressions that express semantic properties of classes and functions. They serve four main purposes: aiding in constructing correct programs, providing documentation, enabling debugging, and serving as the basis for an exception mechanism. The document outlines assertion types like preconditions, postconditions, and class invariants. It provides examples of assertions in C++ and how they support the concept of "programming by contract".

Uploaded by

Esmo Immo
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 18

Object-Oriented Design and

Programming

Programming with Assertions and


Exceptions

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.

 Assertions are similar to the mathematical


notion of a predicate.

 Assertions are tools for expressing and val-


idating the correctness of modules, classes,
and subprograms.

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 :::

 Basis for an exception mechanism.


{ e.g., integrate with exceptions by allowing as-
sertion failures to be caught dynamically.

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;
:::

put (i : INTEGER; value : T) is


require
lower <= i; i <= upper;
do :::

ensure -- post condition


get (i) = value;
end;
invariant -- class invariant
size = upper , lower + 1; size >= 0;
end -- class ARRAY
5
Programming by Contract
 Assertions support Programming by Con-
tract.
{ This formally speci es the relationship between
a class and its clients, expressing each party's
rights and obligations.

 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 :::

 The contract guarantees that if the pre-


condition is ful lled the postcondition holds
upon subprogram return.

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)

 Assertions provide a mechanism to express


the preconditions and axioms correspond-
ing to ADTs.
{ However, few general purpose languages pro-
vide support for complete ADT speci cations,
Ei el goes further than most in this regard.

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.

 It incurs no code size increase and no ex-


ecution speed decrease in the delivered
product.
 Typical de nition via a macro de nition
such as:
#ifdef NDEBUG
#de ne assert(ignore) 0
#else
#de ne assert(ex) \
((ex) ? 1 : \
( eprintf("Failed assertion " #ex \
" at line %d of \%s".\n", \
LINE , FILE ), abort (), 0))
/* Note use of ANSI-C \stringize" facility.
#endif // NDEBUG
9
Assertions in C (cont'd)
 If the expression supplied to the assert
macro is false, an error message will be
printed and the program will STOP DEAD
AT THAT POINT!
 e.g., provide array bounds checking
#include <string.h>
/* */
:::

f
char *callers bu er;
char bu er[100];
/* */:::

assert (sizeof bu er > 1 + strlen (callers bu er));


/* Program aborts here if assertion fails. */
strcpy (bu er, callers bu er);
/* */:::

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\
/* */ \
:::

/* standard assert test code goes here */ \


g

 However, the main problem C assert is


that it doesn't integrate with any excep-
tion handling scheme.
{ e.g., as contrasted to Ei el.

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.

2. To rely on speci c C++ facilities (e.g., tem-


plates and exceptions) to provide a more generic
and powerful support than simple macros.

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 :::

{ A typical example is range checking of a sub-


script operator, as in:
class Checked Vector : public Vector f
public:
class Out Of Range f
int l;
public:
Out Of Range (const char *,
const char *, int line)
: l (line) fg
int line (void) f return l; g
g;
int& Checked Vector::operator[] (int index) f
Assert (index >= 0 && index < size,
Checked Vector::Out Of Range);
// :::
g;
16
Assertions in C++ (cont'd)
 The Assert Macro (cont'd)
{ e.g.,
int f (Checked Vector &v, int index) f
int elem;
try f
elem = v[index];
g
catch (Checked Vector::Out Of Range &e) f
cerr << "Checked Vector:"
<< " range checking failed:"
<< " index="
<< index
<< ", size= " << v.size ()
<< ", line= " << e.line ()
<< 'n';
exit (,1);
g
return elem;
g

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

You might also like