HiveBrain v1.2.0
Get Started
← Back to all entries
debugcppMinor

Simple C++ alternative to exceptions for embedded systems

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
exceptionssimplealternativeembeddedsystemsfor

Problem

I have researched ways to implement a simpler alternative for C++ exceptions. The problem I had with exceptions was the complex and not-portable stack unwinding process which makes it hard to implement for a multiple systems.

However, the alternatives didn't look clean enough to indicate about an error case. In other words, a programmer could easily ignore an error. For example, when using a status code and a result, it can be ignored/mistaken for a result (output). Other alternatives (like, for example exception stack) wasn't modular enough.

My solution is simple: I used a union in order to create an error/value variant. In other words, my class could contain either a return value or an error value.

Example of usage:

Expected
doSomething(bool var) {
    if (val) // Success.
        return {0x30};
    else
        return {ErrorCode::InvalidVar};
}

void callDoSomething() {
    auto maybeRetval = doSomething(false);

    if (maybeRetval) {
        // Success, print result;
        std::cout << maybeRetval.get();
    } else {
        // Failure, print error code:
        std::cout << maybeRetval.getError();
    }
}


The same program with status codes:

ErrorCode 
doSomething(bool var, int *retval) {
    if (var) {
        *retval = 0x30;
        return ErrorCode::OK;
    } else {
        return ErrorCode::InvalidVar;
    }
}

void callDoSomething() {
    int retval;
    ErrorCode errorCode = doSomething(false, &retval);

    if (errorCode != ErrorCode::OK) {
        // Success, print result;
        std::cout << retval;
    } else {
        // Failure, print error code:
        std::cout << errorCode;
    }
}


Expected code:

```
#include

/**
@brief A dynamic variant container for a value, or an error value.
*/
template
class Expected
{
public:
/**
@brief Forward arguments to T's constructor (not error).
*/
template
Expected(Args&&...valueArgs)
: mValue{std::forward(valueArgs)...}, mIsError{false}
{
}

Solution

I like the idea of an "opt-in" exception handling (as in, per function opt-in, rather than globally).

Just a small thing: Your move operator might be faulty. For one, the the argument to the if should likely read expected.mIsError rather than just mIsError. Furthermore, after the move, the contents of expected have been moved out. I think it will be destructed immediately after the move, at which point expected.destruct will still try to destruct one of the two union contents, though none of them is still in a constructed state.

Context

StackExchange Code Review Q#151275, answer score: 2

Revisions (0)

No revisions yet.