Exceptions Bjarne Stroustrup

Slides:



Advertisements
Similar presentations
Chapter 17 vector and Free Store Bjarne Stroustrup
Advertisements

Chapter 19 Vectors, templates, and exceptions Bjarne Stroustrup
Chapter 18 Vectors and Arrays
Chapter 18 Vectors and Arrays John Keyser’s Modification of Slides by Bjarne Stroustrup
Chapter 17 vector and Free Store John Keyser’s Modifications of Slides By Bjarne Stroustrup
C++ Programming Languages
. Smart Pointers. Memory Management u One of the major issues in writing C/C++ code is managing dynamically allocated memory u Biggest question is how.
CSE 332: C++ memory management idioms C++ Memory Management Idioms Idioms are reusable design techniques in a language –We’ll look at 4 important ones.
Exception Handling The purpose of exception handling is to permit the program to catch and handle errors rather than letting the error occur and suffer.
Object Oriented Programming Elhanan Borenstein Lecture #12 copyrights © Elhanan Borenstein.
CSE 332: C++ copy control I Copy Control (Part I) Copy control consists of 5 distinct operations –A copy constructor initializes an object by duplicating.
Lecture 3 Feb 4 summary of last week’s topics and review questions (handout) Today’s goals: Chapter 1 overview (sections 1.4 to 1.6) c++ classes constructors,
API Design CPSC 315 – Programming Studio Fall 2008 Follows Kernighan and Pike, The Practice of Programming and Joshua Bloch’s Library-Centric Software.
Exceptions David Rabinowitz. March 3rd, 2004 Object Oriented Design Course 2 The Role of Exceptions Definition: a method succeeds if it terminates in.
Run time vs. Compile time
Plab – Tirgul 8 Exceptions. Error handling in C Up to now we handled our errors in the “C way”: assert return codes global error variable ( errno and.
C++ / G4MICE Course Session 3 Introduction to Classes Pointers and References Makefiles Standard Template Library.
SNU OOPSLA Lab. 14. Exception Handling © copyright 2001 SNU OOPSLA Lab.
Lecture 11 vector and Free Store Bjarne Stroustrup
1 Chapter 3 Lists, Stacks, and Queues Abstract Data Types, Vectors Sections 3.1, 3.2, 3.3, 3.4 Abstract Data Types (ADT) Iterators Implementation of Vector.
Slides adapted from: Bjarne Stroustrup, Programming – Principles and Practice using C++ Chapter 17 vector and Free Store Hartmut Kaiser
CSCE 121: Introduction to Program Design and Concepts, Honors Dr. J. Michael Moore Spring 2015 Set 3: Objects, Types, and Values 1 Based on slides.
Programming Language C++ Xulong Peng CSC415 Programming Languages.
CSE 332: C++ memory management idioms C++ Memory Management Idioms Idioms are reusable design techniques in a language –We’ll look at 4 important ones.
Copyright  Hannu Laine C++-programming Part 3 Hannu Laine.
Defining New Types Lecture 21 Hartmut Kaiser
1 C++ Classes and Data Structures Jeffrey S. Childs Chapter 5 An Array Class Jeffrey S. Childs Clarion University of PA © 2008, Prentice Hall.
Stacks. A stack is a data structure that holds a sequence of elements and stores and retrieves items in a last-in first- out manner (LIFO). This means.
Pointers OVERVIEW.
Chapter 19 Vectors, templates, and exceptions John Keyser’s Modifications of Slides By Bjarne Stroustrup
Chapter 19 Vectors, templates, and exceptions Bjarne Stroustrup
Memory Management Issues, Solutions, and Examples.
C++ Memory Overview 4 major memory segments Key differences from Java
Pointers and Dynamic Memory Allocation Copyright Kip Irvine 2003, all rights reserved. Revised 10/28/2003.
Exception Handling Programmers must deal with errors and exceptional situations: User input errors Device errors Empty disk space, no memory Component.
Slides adapted from: Bjarne Stroustrup, Programming – Principles and Practice using C++ Chapter 19 Vectors, templates, and exceptions Hartmut Kaiser
Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson Education, Inc. All rights reserved Stacks.
CPSC 252 The Big Three Page 1 The “Big Three” Every class that has data members pointing to dynamically allocated memory must implement these three methods:
C arrays are limited: -they are represented by pointers (which may or may not be valid); -Indexes not checked (which means you can overrun your array);
CS212: Object Oriented Analysis and Design Lecture 20: Exception Handling-II.
CSCE Introduction to Program Design and Concepts J. Michael Moore Spring 2015 Set 17: Vectors and Arrays 1 Based on slides created by Bjarne Stroustrup.
Computer Graphics 3 Lecture 1: Introduction to C/C++ Programming Benjamin Mora 1 University of Wales Swansea Pr. Min Chen Dr. Benjamin Mora.
Effective C++, 2nd Ed. By Scott Myers. Constructors, Destructors, and Assignment Operators 11.Define a copy constructor and an assignment operator for.
CSE 332: C++ Statements C++ Statements In C++ statements are basic units of execution –Each ends with ; (can use expressions to compute values) –Statements.
CSE 332: Memory management with C++ classes Memory Management with Classes Review: for non-static built-in (native) types –default constructor and destructor.
CSCI 383 Object-Oriented Programming & Design Lecture 20 Martin van Bommel.
Standard-Library Exception Safety Bjarne Stroustrup Texas A&M University (and AT&T Labs – Research)
1 Chapter 3 Lists, Stacks, and Queues Reading: Sections 3.1, 3.2, 3.3, 3.4 Abstract Data Types (ADT) Iterators Implementation of Vector.
Chapter 1 C++ Basics Review (Section 1.4). Classes Defines the organization of a data user-defined type. Members can be  Data  Functions/Methods Information.
ICOM 4035 – Data Structures Dr. Manuel Rodríguez Martínez Electrical and Computer Engineering Department Lecture 5 – September 4 th, 2001.
Fall 2015CISC/CMPE320 - Prof. McLeod1 CISC/CMPE320 Assignment 3 is due Sunday, the 8 th at 7pm. Today: –Two simple binding examples. –Function Hiding.
CSCE Introduction to Program Design and Concepts Dr. J. Michael Moore Spring 2015 Set 18: Vectors, Templates and Exceptions 1.
CHAPTER 18 C – C++ Section 1: Exceptions. Error Handling with Exceptions Forces you to defend yourself Separates error handling code from the source.
Data Structures and Algorithm Analysis Dr. Ken Cosh Linked Lists.
Chapter 18 Vectors and Arrays Bjarne Stroustrup
CSE 332: C++ Exceptions Motivation for C++ Exceptions Void Number:: operator/= (const double denom) { if (denom == 0.0) { // what to do here? } m_value.
Jim Fawcett CSE687-OnLine – Object Oriented Design Summer 2017
Jim Fawcett CSE687 – Object Oriented Design Spring 2001
Exceptions David Rabinowitz.
Chapter 18 Vectors and Arrays
Jim Fawcett CSE687 – Object Oriented Design Spring 2015
Chapter 18 Vectors and Arrays
CMSC 202 Lesson 21 Exceptions II.
Abstract Data Types Iterators Vector ADT Sections 3.1, 3.2, 3.3, 3.4
Classes with Dynamically Allocated Data
Chapter 3 Lists, Stacks, and Queues Abstract Data Types, Vectors
Chapter 19 Vectors, templates, and exceptions
Exceptions 2 CMSC 202.
Chapter 19 Vectors, templates, and exceptions
Jordi Cortadella and Jordi Petit Department of Computer Science
Presentation transcript:

Exceptions Bjarne Stroustrup

Stroustrup Fall Interfaces interface is the central concept in programming Implementer User Interface But what about errors?

Stroustrup Fall How do we report run-time errors? Error state int r = f(x,y);// may set errno (yuck!) if (errno) { /* do something */ } Error return codes int r = area(lgt,w);// can return any positive int if (r<=0) { /* do something */ } int r = f(x,y);// f() can return any int (bummer!) (error-code,value) pairs pair rr = are if (rr.first) { /* do something */ } pnt r = rr.second;// good value Exceptions try { int a = area(lgt,w); /* … */ } catch(Bad_area){ /* do something */ }

Stroustrup Fall Exception Handling The problem: provide a systematic way of handling run-time errors –C and C++ programmers use many traditional techniques Error return values, error functions, error state, … Chaos in programs composed out of separately-developed parts –Traditional techniques do not integrate well with C++ Errors in constructors Errors in composite objects –Code using exceptions can be really elegant And efficient

Stroustrup Fall Exception Handling General idea for dealing with non-local errors: –Caller knows (in principle) how to handle an error But cannot detect it (or else if would be a local error) –Callee can detect an error But does not know how to handle it –Let a caller express interest in a type of error try { // do work } catch (Error) { // handle error } –Let a callee exit with an indication of a kind of error throw Error();

Stroustrup Fall Managing Resources //unsafe, naïve use: void f(const char* p) { FILE* f = fopen(p,”r”);// acquire // use f fclose(f);// release }

Stroustrup Fall Managing Resources //naïve fix: void f(const char* p) { FILE* f = 0; try { f = fopen(p,”r”); // use f } catch (…) { // handle exception // … } if (f) fclose(f); }

Stroustrup Fall Managing Resources // use an object to represent a resource (“resource acquisition in initialization”) class File_handle {// belongs in some support library FILE* p; public: File_handle(const char* pp, const char* r) { p = fopen(pp,r); if (p==0) throw Bad_file(); } File_handle(const string& s, const char* r) { p = fopen(s.c_str(),r); if (p==0) throw Bad_file(); } ~File_handle() { if (p) fclose(p); }// destructor // copy operations // access functions }; void f(string s) { File_handle f(s,”r”); // use f }

Stroustrup Fall Invariants To recover from an error we must leave our program in a “good state” Each class has a notion of what is its “good state” –Called its invariant An invariant is established by a constructor class Vector { int sz; int* elem;// elem points to an array of sz ints public: vector(int s) :sz(s), elem(new int(s)) { }// I’ll discuss error handling elsewhere // … };

Stroustrup Fall Exception guarantees Basic guarantee (for all operations) –The basic library invariants are maintained –No resources (such as memory) are leaked Strong guarantee (for some key operations) –Either the operation succeeds or it has no effects No throw guarantee (for some key operations) –The operation does not throw an exception Provided that destructors do not throw exceptions –Further requirements for individual operations

Stroustrup Fall Exception guarantees Keys to practical exception safety Partial construction handled correctly by the language class X { X(int); /* … */ }; class Y { Y(int); /* … */ }; class Z { Z(int); /* … */ }; class D : X, Y { Y m1; Z m2; D(int); /* … */ }; “Resource acquisition is initialization” technique Define and maintain invariants for important types

Stroustrup Fall Exception safety: vector First Space last vector : elements extra space Best vector () representation seems to be (0,0,0)

Stroustrup Fall Exception safety: vector template > class vector { T* v;// start of allocation T* space;// end of element sequence, start of free space T* last;// end of allocation A alloc;// allocator public: // … vector(const vector&); // copy constructor vector& operator=(const vector&); // copy assignment void push_back(const T&); // add element at end size_type size() const { return space-v; } // calculated, not stored };

Stroustrup Fall Unsafe constructor (1) Leaks memory and other resources –but does not create bad vectors template vector ::vector(size_type n, const T& val, const A& a) :alloc(a)// copy allocator { v = a.allocate(n);// get memory for elements space = last = v+n; for (T* p = v; p!=last; ++p) a.construct(p,val);// copy val into elements }

Stroustrup Fall Unititialized_fill() offers the strong guarantee: template void uninitialized_fill(For beg, For end, const T& val) { For p; try { for (p=beg; p!=end; ++p) new(&*p) T(val);// construct } catch (…) {// undo construction for (For q = beg; q!=p; ++q) q->~T();// destroy throw;// rethrow }

Stroustrup Fall Unsafe constructor (2) Better, but it still leaks memory template vector ::vector(size_type n, const T& val, const A& a) :alloc(a)// copy allocator { v = a.allocate(n);// get memory for elements space = last = uninitialized_fill(v,v+n,val);// copy val into elements }

Stroustrup Fall Represent memory explicitly template class vector_base { // manage space public: A& alloc;// allocator T* v;// start of allocated space T* space;// end of element sequence, start of free space T* last;// end of allocated space vector_base(const A&a, typename A::size_type n) :alloc(a), v(a.allocate(n)), space(v+n), last(v+n) { } ~vector_base() { alloc.deallocate(v,last-v); } }; // works best if a.allocate(0)==0 // we have assumed a stored allocator for convenience

Stroustrup Fall A vector is something that provides access to memory template > class vector : private vector_base { void destroy_elements() { for(T* p = v; p!=space; ++p) p->~T(); } public: // … explicit vector(size_type n, const T& v = T(), const A& a = A()); vector(const vector&); // copy constructor vector& operator=(const vector&); // copy assignment ~vector() { destroy_elements(); } void push_back(const T&); // add element at end size_type size() const { return space-v; } // calculated, not stored // … };

Stroustrup Fall Exception safety: vector Given vector_base we can write simple vector constructors that don’t leak template vector ::vector(size_type n, const T& val, const A& a) : vector_base(a,n)// allocate space for n elements { uninitialized_fill(v,v+n,val);// initialize }

Stroustrup Fall Exception safety: vector Given vector_base we can write simple vector constructors that don’t leak template vector ::vector(const vector& a) : vector_base(a.get_allocator(),a.size()) // allocate space for a.size() elements { uninitialized_copy(a.begin(),a.end(),v);// initialize }

Stroustrup Fall But how do you handle errors? Where do you catch? –Multi-level? Did you remember to catch? –Static vs. dynamic vs. no checking

Stroustrup Fall Reserve() is key That’s where most of the tricky memory management reside template void vector ::reserve(int newalloc) { if (newalloc<=space) return;// never decrease allocation vector_base b(alloc,newalloc); // allocate new space for (int i=0; i<sz; ++i) alloc.construct(&b.elem[i],elem[i]);// copy for (int i=0; i<sz; ++i) alloc.destroy(&elem[i],space); // destroy old swap >(*this,b);// swap representations }

Stroustrup Fall Push_back() is (now) easy template void vector ::push_back(const T& val) { if (sz==space) reserve(sz?2*space):4;// get more space alloc.construct(&elem[sz],d);// add d at end ++sz;// increase the size }

Stroustrup Fall Resize() Similarly, vector ::resize() is not too difficult: template void vector ::resize(int newsize, T val = T()) { reserve(newsize); for (int i=sz; i<newsize; ++i) alloc.construct(&elem[i],val); // construct for (int i = newsize; i<sz; ++i) alloc.destroy(&elem[i]); // destroy sz = newsize; }

Stroustrup Fall Exception safety: vector Naïve assignment (unsafe) template Vector & Vector ::operator=(const vector& a) { destroy_elements(); // destroy old elements alloc.deallocate(v);// free old allocation alloc = a.get_allocator();// copy allocator v = alloc.allocate(a.size());// allocate for (int i = 0; i<a.size(); i++) v[i] = a.v[i];// copy elements space = last = v+a.size(); return *this; }

Stroustrup Fall Assignment with strong guarantee template Vector & Vector ::operator=(const vector& a) { vector temp(a);// copy vector swap >(*this,temp);// swap representations return *this; } Note: –The algorithm is not optimal What if the new value fits in the old allocation? –The implementation is optimal –No check for self assignment (not needed) –The “naïve” assignment simply duplicated code from other parts of the vector implementation

Stroustrup Fall Optimized assignment (1) template Vector & Vector ::operator=(const vector& a) { if (capacity() < a.size()) {// allocate new vector representation vector temp(a); swap >(*this,temp); return *this; } if (this == &a) return *this;// self assignment // copy into existing space return *this; }

Stroustrup Fall Optimized assignment (2) template Vector & Vector ::operator=(const vector& a) { // … size_type sz = size(); size_type asz = a.size(); alloc = a.get_allocator(); if (asz<=sz) { copy(a.begin(),a.begin()+asz,v); for (T* p =v+asz; p!=space; ++p) p->~T();// destroy surplus elements } else { copy(a.begin(),a.begin()+sz,v); uninitialized_copy(a.begin()+sz,a.end(),space);// construct extra elements } space = v+asz; return *this; }

Stroustrup Fall Optimized assignment (3) The optimized assignment –19 lines of code 3 lines for the unoptimized version –offers the basic guarantee not the strong guarantee –can be an order of magnitude faster than the unoptimized version depends on usage and on free store manager –is what the standard library offers I.e. only the basic guarantee is offered But your implementation may differ and provide a stronger guarantee

Stroustrup Fall Exception safety Rules of thumb: –Decide which level of fault tolerance you need Not every individual piece of code needs to be exception safe –Aim at providing the strong guarantee –Always provide the basic guarantee if you can’t afford the strong guarantee Keep a good state (usually the old state) until you have constructed a new state; then update “atomically” –Define “good state” (invariant) carefully Establish the invariant in constructors (not in “init() functions”) –Minimize explicit try blocks –Represent resources directly Prefer “resource acquisition is initialization” over code where possible Avoid “free standing” news and deletes –Keep code highly structured (“stylized”) “random code” easily hides exception problems

Stroustrup Fall To do Read –TC++PL Appendix E and/or –B. Stroustrup: Exception Safety: Concepts and Techniques. LNCS –Further reading: Sutter on “Exceptional C++ Dave Abrahams on exception safety/guarantee Jonathan L. Schilling: Optimizing Away C++ Exception Handling ( e=pdf) e=pdf Try Google and/or Wikipedia To do –How much does it cost to throw an exception? –Measure some variants of void f(int n) { vector v(100); if (n) f(n-1); throw 2; }