CS253: Software Development with C++

Fall 2019

Old-fashioned Error Handling

Show Lecture.Old-fashionedErrorHandling as a slide show.

CS253 Old-fashioned Error Handling

The Old Days

Out-of-band value

#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']

That works, but …

exit

#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']

abort

#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

assert

#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

Division by Zero

#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

The Horror That Is Setjmp/Longjmp

#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']