Click here to Skip to main content
Click here to Skip to main content

Tagged as

Exception unsafe

, 26 Apr 2012
Rate this:
Please Sign up or sign in to vote.
What it means for code to satisfy the basic exception safety guarantee.

I was reading up about exception safe code in C++ and the difference between the strong and basic exception guarantees. The article here (http://www.gotw.ca/gotw/082.htm) outlines what it means for code to satisfy the basic exception safety guarantee, however it doesn’t give an example. So I came up with something that is exception unsafe. The code below doesn’t satisfy the basic guarantee because it fails to delete the memory allocated to the pointer.

Exception unsafe.

#include <iostream>
#include <stdexcept>

using namespace std;

void h()
{
  throw logic_error((string("Failure in ") + string(__func__)));
}

void g()
{
  int* pi = new int;
  h();
  delete pi;
}

void f()
{
  try
  {
    g();
  }
  catch (const exception& e)
  {
    cout << e.what() << endl;
  }
}

int main(int argc, char** argv)
{
  f();
}

To ensure that it meets the basic guarantee the exception needs to be caught in g() and the memory deallocated. The code below does this. Unfortunately there is a bit of awkwardness here: note the double delete. One is in the bad path where the exception is caught and the other is in the good code path. It would be nice if the double delete wasn’t necessary. Other languages have a finally statement that is executed in both the good and bad case, however C\++ doesn’t have this but the problem is still solvable as shown below.

Basic exception safety met.

#include <iostream>
#include <stdexcept>

using namespace std;

void h()
{
  throw logic_error((string("Bad logic in ") + string(__func__)));
}

void g()
{
  int* pi = new int;
  try
  {
    h();
  }
  catch (const exception& e)
  {
    cout << "Caught exception: \"" << e.what() << "\" in " << __func__  << endl;
    delete pi;
    throw;
  }
  delete pi;
}

void f()
{
  try
  {
    g();
  }
  catch (const exception& e)
  {
    cout << "Caught exception: \"" << e.what() << "\" in " << __func__  << endl;
  }
}

int main(int argc, char** argv)
{
  f();
}

The lack of a finally statement in C++ isn’t a problem as long as the principle Resource Acquisition is Initialization is applied. It’s fairly straightforward and with a little bit of thought I think that most good programmers would realize what to do here in order to avoid having a double delete. The trick is to write a wrapper class to manage the resource and in the destructor clean up any allocated memory. If you follow this guideline then there is no need for C++ to have a finally statement. This is mentioned in the the C++ FAQ in section 17.6. The following code applies RAII. I’ve found myself doing this in code I’ve writted without explicitly realizing the technique I was applying had a name assoiciated with it.

Basic exception safety with RAII.

#include <iostream>
#include <stdexcept>

using namespace std;

class Resource
{
  private:
    int* pi;

  public:
    Resource()
    {
      cout << __func__ << endl;
      pi = new int;
    }

    ~Resource()
    {
      cout << __func__ << endl;
      delete pi;
    }
};

void h()
{
  throw logic_error((string("Bad logic in ") + string(__func__)));
}

void g()
{
  Resource r;
  h();
}

void f()
{
  try
  {
    g();
  }
  catch (const exception& e)
  {
    cout << "Caught exception: \"" << e.what() << "\" in " << __func__  << endl;
  }
}

int main(int argc, char** argv)
{
  f();
}

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

sashan govender

Australia Australia
No Biography provided

Comments and Discussions

 
GeneralMy vote of 3 PinmemberAescleal27-Apr-12 1:54 
GeneralRe: My vote of 3 Pinmembersashan govender29-Apr-12 22:09 
QuestionGood Pinmembersurajfrommumbai26-Apr-12 20:37 
AnswerRe: Good PinmemberAescleal27-Apr-12 1:55 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web02 | 2.8.140821.2 | Last Updated 26 Apr 2012
Article Copyright 2012 by sashan govender
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid