CS253: Software Development with C++

Spring 2020

Old-fashioned Error Handling

Show Lecture.Old-fashionedErrorHandling as a slide show.

CS253 Old-fashioned Error Handling

The Old Days

Out-of-band value

Out-of-band value

Loud a='a';

double invert(double num) {
    Loud b('b');
    if (num == 0)
        return NAN;
    return 1/num;
}

int main() {
    Loud c('c');
    double result = invert(0);
    if (isnan(result))
        return 1;
    cout << result << '\n';
}
Loud::Loud() [c='a']
Loud::Loud() [c='c']
Loud::Loud() [c='b']
Loud::~Loud() [c='b']
Loud::~Loud() [c='c']
Loud::~Loud() [c='a']

NAN is the floating-point Not-A-Number value. isnan() detects it. Maybe return INFINITY?

That works, but …

exit

Loud a='a';

double invert(double num) {
    Loud b('b');
    if (num == 0)
        exit(1);
    return 1/num;
}

int main() {
    Loud c('c');
    cout << invert(0) << '\n';
}
Loud::Loud() [c='a']
Loud::Loud() [c='c']
Loud::Loud() [c='b']
Loud::~Loud() [c='a']

abort

Loud a='a';

double invert(double num) {
    Loud b('b');
    if (num == 0)
        abort();
    return 1/num;
}

int main() {
    Loud c('c');
    cout << invert(0) << '\n';
}
Loud::Loud() [c='a']
Loud::Loud() [c='c']
Loud::Loud() [c='b']
SIGABRT: Aborted

assert

Loud a='a';

double invert(double num) {
    Loud b('b');
    assert(num);
    return 1/num;
}

int main() {
    Loud c('c');
    cout << invert(0) << '\n';
}
Loud::Loud() [c='a']
Loud::Loud() [c='c']
Loud::Loud() [c='b']
a.out: c.cc:5: double invert(double): Assertion `num' failed.
SIGABRT: Aborted

Division by Zero

Loud a='a';
static int z = 0;

double invert(double num) {
    Loud b('b');
    if (num == 0)
        z = 1/z;
    return 1/num;
}

int main() {
    Loud c('c');
    cout << invert(0) << '\n';
}
Loud::Loud() [c='a']
Loud::Loud() [c='c']
Loud::Loud() [c='b']
SIGFPE: Floating point exception

The Horror That Is Setjmp/Longjmp

Loud a='a';
jmp_buf env;

double invert(double num) {
    Loud b('b');
    if (num == 0)
        longjmp(env, 456);
    return 1/num;
}

int main() {
    Loud c('c');
    if (int val = setjmp(env)) {
        cout << "error=" << val << "!\n";
        return 1;
    }
    cout << invert(0) << '\n';
}
Loud::Loud() [c='a']
Loud::Loud() [c='c']
Loud::Loud() [c='b']
error=456!
Loud::~Loud() [c='c']
Loud::~Loud() [c='a']