Show Lecture.Old-fashionedErrorHandling as a slide show.
#include "Loud.h" #include <unistd.h> Loud a='a'; int foo() { Loud b('b'); if (getuid() != 0) // root? return -1; return 42; } int main() { Loud c('c'); if (foo() < 0) return 1; Loud d('d'); return 0; }
Loud::Loud() [c='a'] Loud::Loud() [c='c'] Loud::Loud() [c='b'] Loud::~Loud() [c='b'] Loud::~Loud() [c='c'] Loud::~Loud() [c='a']
foo()
needs to check for errors, and return early.
#include "Loud.h" #include <unistd.h> Loud a='a'; void foo() { Loud b('b'); // MUST be super-user! if (getuid() != 0) exit(1); } int main() { Loud c('c'); foo(); Loud d('d'); return 0; }
Loud::Loud() [c='a'] Loud::Loud() [c='c'] Loud::Loud() [c='b'] Loud::~Loud() [c='a']
#include "Loud.h" #include <unistd.h> Loud a='a'; void foo() { Loud b('b'); if (getuid() != 0) abort(); } int main() { Loud c='c'; foo(); Loud d='d'; return 0; }
Loud::Loud() [c='a'] Loud::Loud() [c='c'] Loud::Loud() [c='b'] SIGABRT: Aborted
#include "Loud.h" #include <cassert> #include <unistd.h> Loud a('a'); void foo() { Loud b('b'); assert(!getuid()); } int main() { Loud c('c'); foo(); Loud d('d'); return 0; }
Loud::Loud() [c='a'] Loud::Loud() [c='c'] Loud::Loud() [c='b'] a.out: c.cc:9: void foo(): Assertion `!getuid()' failed. SIGABRT: Aborted
#include "Loud.h" #include <unistd.h> Loud a('a'); static int n = 0; void foo() { Loud b('b'); if (getuid() != 0) n = 1/n; } int main() { Loud c('c'); foo(); Loud d('d'); return 0; }
Loud::Loud() [c='a'] Loud::Loud() [c='c'] Loud::Loud() [c='b'] SIGFPE: Floating point exception
#include <csetjmp> #include <iostream> #include "Loud.h" using namespace std; Loud a('a'); jmp_buf env; void foo() { Loud b('b'); longjmp(env, 456); } int main() { if (int val = setjmp(env)) { cout << "error=" << val << "!\n"; return 1; } Loud c('c'); foo(); Loud d('d'); return 0; }
Loud::Loud() [c='a'] Loud::Loud() [c='c'] Loud::Loud() [c='b'] error=456! Loud::~Loud() [c='a']