Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: fixed color of noncompliant code block

...

Calling longjmp() prevents local class variables from being properly destroyed, as can be demonstrated by the following code:

Code Block
bgColor#ccccff#FFcccc

#include <csetjmp>
#include <iostream>
using namespace std;

static jmp_buf env;

class Counter {
public:
  static int Instances;

  Counter() {Instances++;}
  ~Counter() {Instances--;}
private:
  Counter(const Counter& that);
  Counter& operator=(const Counter& that);
};

int Counter::Instances = 0;
class Error {};

void func() {
  Counter c;
  cout << "func(): Instances: " << Counter::Instances << endl;
  longjmp( env, 1);
}

int main() {

  cout << "Before setjmp(): Instances: " << Counter::Instances << endl;
  if (setjmp(env) == 0) {
    func();
  } else {
    cout << "From longjmp(): Instances: " << Counter::Instances << endl;
  }

  cout << "After longjmp(): Instances: " << Counter::Instances << endl;
}

...

Use exceptions instead of setjmp() and longjmp(), as throwing exceptions will still invoke destructors of local class variables.

Code Block
bgColor#ccccff

#include <iostream>
using namespace std;

class Counter {
public:
  static int Instances;

  Counter() {Instances++;}
  ~Counter() {Instances--;}
private:
  Counter(const Counter& that);
  Counter& operator=(const Counter& that);
};

int Counter::Instances = 0;
class Error {};

void func() {
  Counter c;
  cout << "func(): Instances: " << Counter::Instances << endl;
  throw Error();
}

int main() {

  cout << "Before try: Instances: " << Counter::Instances << endl;
  try {
    func();
  } catch (...) {
  cout << "In catch: Instances: " << Counter::Instances << endl;
  }

  cout << "After catch: Instances: " << Counter::Instances << endl;
}

...