• std::expected performance tradeoff

    From nyuhu@3:633/10 to All on Mon Jul 6 02:30:43 2026
    Hi,

    I?ve been thinking for a while about giving monads a try in C++, and as
    a starting point I?m looking at using std::expected[1] as an error
    handling strategy.

    I am trying to figure out if I would be okay with the performance
    tradeoff in a kernel driver or embedded environment.

    So, a typical error code based style could be structured like this
    ```cpp
    #include <cstdlib>

    enum class return_code
    {
    ok,
    bad_input,
    bad_luck,
    };

    return_code do_something(int *result)
    {
    if (!result) return return_code::bad_input;
    int res = std::rand();
    if (!res) return return_code::bad_luck;
    *result = res;
    return return_code::ok;
    }

    int main(int argc, char *argv[])
    {
    int val = 0;
    return_code err = do_something(&val);
    if (err == return_code::ok) {
    // Happy path, can use val
    } else {
    // Error path, handle err
    }
    return 0;
    }
    ```

    And if using std::expected we can do
    ```cpp
    #include <cstdlib>
    #include <expected>

    enum class error_code
    {
    // No need for an OK error code
    bad_luck,
    };

    // No need for a result parameter passed by reference
    std::expected<int, error_code> do_something()
    {
    int res = std::rand();
    if (!res) return std::unexpected(error_code::bad_luck);
    return res;
    }

    int main(int argc, char *argv[])
    {
    auto val = do_something();
    if (val.has_value()) {
    // Happy path, can use *val
    } else {
    // Error path, handle val.error()
    }
    return 0;
    }
    ```

    This is a trivial example so the readability gain might not be that
    convincing to everyone, but I?m sure we could come up with nicer ones
    that use other member functions like `value_or`, `and_then`.

    I tried getting a sense of the performance tradeoff of adopting this
    class, and I ran into an article[2] that suggests the std::expected way
    is twice as slow as the error code approach (0.00707 ęs vs 0.00329 ęs).
    For very sporadic uses that is probably negligible, but as an overall
    error handling strategy throughout an entire code base, the answer is up
    for debate (and very context specific).

    Any relevant war stories or feedback from people who already dealt with
    this topic?

    [1] https://en.cppreference.com/cpp/utility/expected
    [2] \ https://johnfarrier.com/c-error-handling-strategies-benchmarks-and-performance/

    --
    nyuhu

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)