Click here to Skip to main content
15,884,388 members
Articles / Programming Languages / C++

Exception Unsafe

Rate me:
Please Sign up or sign in to vote.
3.00/5 (1 vote)
26 Apr 2012CPOL2 min read 8.1K   1   4
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

C++
#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

C++
#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 C++ FAQ in section 17.6. The following code applies RAII. I’ve found myself doing this in code I’ve written without explicitly realizing the technique I was applying had a name associated with it.

Basic Exception Safety with RAII

C++
#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)


Written By
Australia Australia
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralMy vote of 3 Pin
Aescleal27-Apr-12 1:54
Aescleal27-Apr-12 1:54 
GeneralRe: My vote of 3 Pin
sashan govender29-Apr-12 22:09
sashan govender29-Apr-12 22:09 
QuestionGood Pin
surajfrommumbai26-Apr-12 20:37
surajfrommumbai26-Apr-12 20:37 
AnswerRe: Good Pin
Aescleal27-Apr-12 1:55
Aescleal27-Apr-12 1:55 

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

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