Writing “Exception Safe” C++ Alan Griffiths –Work: Experian Limited Senior Systems Consultant Mentoring & development OOA/OOD/C++

Slides:



Advertisements
Similar presentations
Chapter 18 Vectors and Arrays
Advertisements

Exceptions CSE301 University of Sunderland Harry Erwin, PhD.
Chapter 16 Exception Handling. What is Exception Handling? A method of handling errors that informs the user of the problem and prevents the program from.
Chapter 18 Vectors and Arrays John Keyser’s Modification of Slides by Bjarne Stroustrup
Writing Modern C++ Marc Grégoire Software Architect April 3 rd 2012.
What's new in Microsoft Visual C Preview
Introduction to Programming Lecture 39. Copy Constructor.
CMSC 202, Version 2/02 1 Operator Overloading Strong Suggestion: Go over the Array class example in Section 8.8 of your text. (You may ignore the Array.
1 Abstract Data Types Chapter 1. 2 Objectives You will be able to: 1. Say what an abstract data type is. 2. Implement a simple abstract data type in C++
CSC241 Object-Oriented Programming (OOP) Lecture No. 9.
C++ Programming Languages
Win32 Programming Lesson 4: Classes and Structures.
4/29/20151 Java Exceptions. 4/29/20152 Overview An exception is an unusual circumstance, such as an error condition, that must be handled in a non-standard.
. 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.
CS Advanced C++ Exception Handling Topic #5.
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,
The Standard Template Library – part 2. auto_ptr Regular pointers may cause memory leaks Regular pointers may cause memory leaks void f() { SomeClass.
CS 326 Programming Languages, Concepts and Implementation Instructor: Mircea Nicolescu Lecture 18.
1 Pointers A pointer variable holds an address We may add or subtract an integer to get a different address. Adding an integer k to a pointer p with base.
Exceptions Amit Shabtay. March 3rd, 2004 Object Oriented Design Course 2 Covariance\Contravariance Reminder class Parent { void test (covar : Mammal,
C Programming Basics Lecture 5 Engineering H192 Winter 2005 Lecture 05
. Plab – Tirgul 10 Exceptions. Error handling in C Up to now we handled our errors in the “C way”: assert return codes global error variable ( errno and.
CSSE221: Software Dev. Honors Day 27 Announcements Announcements Projects turned in? Projects turned in? The 2 required Angel surveys are due by 9 pm tonight.
Template class Wrapper { public: T* operator->() { return &myT; } private: T myT; }; int main() { Wrapper wThing; wThing- >Foo(); // calls Thing::Foo()...
Exceptions David Rabinowitz. March 3rd, 2004 Object Oriented Design Course 2 The Role of Exceptions Definition: a method succeeds if it terminates in.
Review on pointers and dynamic objects. Memory Management  Static Memory Allocation  Memory is allocated at compiling time  Dynamic Memory  Memory.
COMP 14: Intro. to Intro. to Programming May 23, 2000 Nick Vallidis.
C ++ Programming Languages Omid Jafarinezhad Lecturer: Omid Jafarinezhad Fall 2013 Lecture 2 C ++ -overview Department of Computer Engineering 1.
From C++ to C#. Web programming The course is on web programming using ASP.Net and C# The course is on web programming using ASP.Net and C# ASP.Net is.
CSE 332: C++ templates and generic programming I Motivation for Generic Programming in C++ We’ve looked at procedural programming –Reuse of code by packaging.
CSE333 SECTION 7. Template vs Generics C++ templates are similar to preprocessor macros A template will be “materialized” into multiple copies with T.
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.
Chapter 0.2 – Pointers and Memory. Type Specifiers  const  may be initialised but not used in any subsequent assignment  common and useful  volatile.
1 Linked Stack Chapter 4. 2 Linked Stack We can implement a stack as a linked list. Same operations. No fixed maximum size. Stack can grow indefinitely.
1 C++ Classes and Data Structures Jeffrey S. Childs Chapter 5 An Array Class Jeffrey S. Childs Clarion University of PA © 2008, Prentice Hall.
C++ History C++ was designed at AT&T Bell Labs by Bjarne Stroustrup in the early 80's Based on the ‘C’ programming language C++ language standardised in.
Memory Management Issues, Solutions, and Examples.
C++ Memory Overview 4 major memory segments Key differences from Java
 Managing the heap  Resource acquisition is initialization (RAII)  Overriding operator new and delete  Class-based memory pools.
Engineering H192 - Computer Programming The Ohio State University Gateway Engineering Education Coalition Lect 5P. 1Winter Quarter C Programming Basics.
Instructor: Alexander Stoytchev CprE 185: Intro to Problem Solving (using C)
Exception Handling Programmers must deal with errors and exceptional situations: User input errors Device errors Empty disk space, no memory Component.
CMSC 202, Version 3/02 1 Copy Constructors and Overloaded Assignment.
Writing Correct C++ Programs without “delete” Huang-Ming Huang CSE332 Guest Lecture Washington University in St. Louis.
Engineering H192 - Computer Programming Gateway Engineering Education Coalition Lect 5P. 1Winter Quarter C Programming Basics Lecture 5.
Quick Review of OOP Constructs Classes:  Data types for structured data and behavior  fields and methods Objects:  Variables whose data type is a class.
CHAPTER 18 C – C++ Section 1: Exceptions. Error Handling with Exceptions Forces you to defend yourself Separates error handling code from the source.
Exceptions and Error Handling. Exceptions Errors that occur during program execution We should try to ‘gracefully’ deal with the error Not like this.
FASTFAST All rights reserved © MEP Make programming fun again.
Effective C# 50 Specific Ways to Improve Your C# Item 44 ~ 45 Kevin2012/9/26 1.
C++ Catastrophes “if C allows you to shoot yourself in the foot, then C++ is giving you a machine gun!” James Prince.
C ++ MULTIPLE CHOICE QUESTION
Exceptions Error Handling and Recovery
Jim Fawcett CSE687-OnLine – Object Oriented Design Summer 2017
Jim Fawcett CSE687 – Object Oriented Design Spring 2001
Exceptions David Rabinowitz.
Chapter 6 CS 3370 – C++ Functions.
Jim Fawcett CSE687 – Object Oriented Design Spring 2015
C++ Memory Management Idioms
C++ History C++ was designed at AT&T Bell Labs by Bjarne Stroustrup in the early 80's Based on the ‘C’ programming language C++ language standardised in.
LinkedList Class.
CMSC 202 Lesson 21 Exceptions II.
Exceptions 2 CMSC 202.
Practical Session 4 Rule of 5 R-value reference Unique pointer
Software Engineering Lecture #35
Objects Managing a Resource
Presentation transcript:

Writing “Exception Safe” C++ Alan Griffiths –Work: Experian Limited Senior Systems Consultant Mentoring & development OOA/OOD/C++ –Play: WWW, Java –ACCU chairman

Overview This talk breaks down into the following sections: –What we mean by “exception safety” –The problems of a naïve approach –Guidelines and a rewrite –Applying these techniques

Timeline ARM: Exceptions (experimental) 1995Q1 CD1: Exceptions in language but Q4 CD2: …library not exception safe 1997ish - Many exception-safety articles ISO Standard - “Exceptions safe”

Some of the articles  H Muller - “Ten rules for handling exception handling successfully” – C++ Report Jan.’96  H Sutter - “Designing exception-safe Generic Containers” – C++ Report Sept.’97  H Sutter - “More exception-safe Generic Containers” – C++ Report Nov-Dec.’97  K Henney – “Creating Stable Assignments” – C++ Report June’98

Writing “Exception Safe” C++  What we mean by “exception safety” –The problems of a naïve approach –Guidelines and a rewrite –Applying these techniques

Call stack: a() to x() a() calls b() … e() calls f() f() calls g() … x() throws an exception [handled by a()]. x() line 1... g() line bytes f() line bytes e() line bytes... a() line bytes main() line 360 mainCRTStartup() line bytes

f() is exception safe if... The weak exception safety guarantee –No resources are leaked –The system state remains valid The strong exception safety guarantee –If f() terminates by propagating an exception then it makes no change to the state of the program.

Divide and conquer f() relies on g(), h(), …, x() Objects isolate changes

Other definitions There are other definitions of exception safe. –For example “deleteable” –You may have encountered others… –Some references in the notes

Recap: “exception safety” The “weak exception safety guarantee” requires: –Resources are not leaked –The system state remains valid In addition the “strong exception safety guarantee” requires: –There is no change to the system state

Writing “Exception Safe” C++  What we mean by “exception safety”  The problems of a naïve approach –Guidelines and a rewrite –Applying these techniques

How do we write f()?

class PartOne { /* omitted */ }; class PartTwo { /* omitted */ }; class Whole { public: //...Lots omitted... Whole& operator=(const Whole& rhs); private: PartOne*p1; PartTwo*p2; };

Assignment operator Whole& Whole::operator=(const Whole& rhs){ if (&rhs != this) { delete p1; delete p2; p1 = new PartOne(*rhs.p1); p2 = new PartTwo(*rhs.p2); } return *this; } Don’t do it this way!!!

Whole& Whole::operator=(const Whole& rhs) { if (&rhs != this) { PartOne* t1 = new PartOne(*rhs.p1); try { PartTwo* t2 = new PartTwo(*rhs.p2); delete p1; delete p2; p1 = t1; p2 = t2; } catch (...) { delete t1; throw; } } return *this; } The naïve approach PartOne* t1 = new PartOne(*rhs.p1); try { PartTwo* t2 = new PartTwo(*rhs.p2); delete p1; delete p2; p1 = t1; p2 = t2; } catch (...) { delete t1; throw; }

naïve approach - assessment Good software engineering: –So simple that there are “obviously no errors” This approach: –So complex that there are “no obvious errors”

Writing “Exception Safe” C++  What we mean by “exception safety”  The problems of a naïve approach  Guidelines and a rewrite –Applying these techniques

The guidelines There are three rules: –Destructors may not propagate exceptions –States may be swapped without an exception being thrown –An object may own at most one resource

The revised example class Whole { public: //...Lots omitted... Whole& operator=(const Whole& rhs); private: std::auto_ptr p1; std::auto_ptr p2; };

revised assignment operator Whole& Whole::operator=(const Whole& rhs) { std::auto_ptr t1(new PartOne(*rhs.p1)); std::auto_ptr t2(new PartTwo(*rhs.p2)); swap(p1, t1); swap(p2, t2); return *this; }

assignment operator - again Whole& Whole::operator=(const Whole& rhs) { Whole(rhs).swap(*this); return *this; } void Whole::swap(Whole& that) { using std::swap; swap(p1, that.p1); swap(p2, that.p2); }

Recap: the guidelines Destructors may not propagate exceptions States may be swapped without an exception being thrown An object may own at most one resource

Writing “Exception Safe” C++  What we mean by “exception safety”  The problems of a naïve approach  Guidelines and a rewrite  Applying these techniques

A smart pointer arg::body_part_ptr<> –When an std::auto_ptr<> is copied ownership is transferred –body_part_ptr<> copies the object pointed to by the assigned pointer

Another version of Whole class Whole { public: //...Lots omitted... Whole& operator=(const Whole& rhs); void swap(Whole& that); private: arg::body_part_ptr p1; arg::body_part_ptr p2; };

The latest implementation Whole& Whole::operator=(const Whole& rhs) { Whole(rhs).swap(*this); return *this; } void Whole::swap(Whole& that) { using std::swap; swap(p1, that.p1); swap(p2, that.p2); }

Specialising std::swap namespace std { inline void swap( ::example5::Whole& lhs, ::example5::Whole& rhs) { lhs.swap(rhs); } }

Base classes Health warning don’t do this at home

Extended Whole Whole& Whole::setP1(const PartOne& value) { p1.reset(new PartOne(value)); return *this; } Whole& Whole::setP2(const PartTwo& value) { p2.reset(new PartTwo(value)); return *this; }

class ExtendedWhole : private Whole { public: /* Omit constructors & assignment */ void swap(const ExtendedWhole& rhs); void setParts( const PartOne& p1, const PartTwo& p2, const PartThree& p3); private: int count; PartThree body; };

ExtendedWhole::swap() void ExtendedWhole::swap( ExtendedWhole& rhs) { using std::swap; Whole::swap(*this); swap(count, rhs.count); swap(body, rhs.body); }

ExtendedWhole::setParts() void ExtendedWhole::setParts( const PartOne& p1, const PartTwo& p2, const PartThree& p3) { setP1(p1); setP2(p2); body = p3; }

ExtendedWhole::setParts() void ExtendedWhole::setParts( const PartOne& p1, const PartTwo& p2, const PartThree& p3) { Whole temp(*this); temp.setP1(p1).setP2(p2); body = p3; Whole::swap(temp); }

“Strong” or “Weak” guarantee? Choose a design when designing a function –Strong is more convenient for user –Weak requires fewer copies and temporaries Document the library, class or function Implement the design decision correctly I don’t know of automated tools

Writing “Exception Safe” C++  What we mean by “exception safety”  The problems of a naïve approach  Guidelines and a rewrite  Applying these techniques

#include int main() { struct local_file { local_file() : f(std::fopen(__FILE__, "r")) {} ~local_file() { if (f) std::fclose(f); } operator std::FILE* () const { return f; } std::FILE* f; } file; char buffer[1000]; if (file) { std::fread(buffer, sizeof buffer, 1, file); // Processing that may throw an exception } return 0; } struct local_file { local_file() : f(std::fopen(__FILE__, "r")) {} ~local_file() { if (f) std::fclose(f); } operator std::FILE* () const { return f; } std::FILE* f; } file;

Example for discussion counted_ptr ptr(new T()); needs a counter allocation could fail so may constructor throw? and should it delete initialiser?

H Muller - “Ten rules for handling exception handling successfully” – C++ Report Jan.’96 H Sutter - “Designing exception-safe Generic Containers” – C++ Report Sept.’97 H Sutter - “More exception-safe Generic Containers” – C++ Report Nov-Dec.’97 K Henney – “Creating Stable Assignments” – C++ Report June’98 D Abrahams - "Exception Safety in STLport” -