title: Exception Safety- When, How, Why?
body: <p>I'm just a fledgling programmer that at least tries to program more than the best-case scenario. I've been reading Herb Sutter's "Exceptional C++" and went through the exception-safety chapters thrice so far. However, barring the example he posed (a Stack), I'm not really sure when exactly I should strive for exception safety vs speed and when it's just plain silly to do so.</p>
  
  <p>For example, my current homework project is a doubly-linked list. Since I've programmed a couple of these already, I wanted to take the time to get into some deeper concepts such as ES. </p>
  
  <p>Here is my pop-front function:</p>
  
  <pre><code>void List::pop_front()
  {
      if(!head_)
          throw std::length_error("Pop front:  List is empty.\n");
      else
      {
          ListElem *temp = head_;
          head_          = head_-&gt;next;
          head_-&gt;prev    = 0;
          delete temp;
          --size_;
      }
  }
  </code></pre>
  
  <p>I had some dilemmas with this. </p>
  
  <p>1) Should I really throw an error when a list fails? Shouldn't I rather simply do nothing and return instead of forcing the user of the list to perform try {] catch() {} statements (that are also slow).</p>
  
  <p>2) There are multiple error classes (plus the ListException my teacher demands we implement in the class). Is a custom error class really necessary for such a thing, and is there a general guide on when to use a specific exception class? (For example, range, length and boundary all sound alike)</p>
  
  <p>3) I know I shouldn't change the program state until all that code that has thrown an exception be done. This is why I'm decrementing size_ last. Is this really necessary in this simple example? I know delete can't throw. Is it possible for head_->prev to ever throw when assigning to 0? (head is the first Node)</p>
  
  <p>My push_back function:</p>
  
  <pre><code>void List::push_back(const T&amp; data)
  {
      if(!tail_)
      {
          tail_ = new ListElem(data, 0, 0);
          head_ = tail_;
      }
      else
      {
      tail_-&gt;next = new ListElem(data, 0, tail_);
      tail_ = tail_-&gt;next;
      }
      ++size_;
  }
  </code></pre>
  
  <p>1) I hear often that <em>anything</em> can fail in a C++ program. Is it realistic to test if the constructor for ListElem fails (or tail_ during <code>new</code>ing)? </p>
  
  <p>2) Would it ever be necessary to test the type of data (currently a simple <code>typedef int T</code> until I templatize everything) to make sure the type is viable for the structure?</p>
  
  <p>I realize that these are overly simple examples, but I'm currently just confused as to when I should actually practice good ES and when it's not.</p>