cpp:S6023 fails to take into account eager evaluation

The following code triggers cpp:S6023 (Simplify this code by using “std::optional” member function “value_or”)

int demo(std::optional<int> x, int y)
{
    if (x.has_value())
        return x.value();
    else
        return slow_calculation(y);
}

This seems not to take into account that value_or is a normal function so the argument is evaluated eagerly: replacing the function with

int demo(std::optional<int> x, int y)
{
    return x.value_or(slow_calculation(y));
}

would end up running the slow_calculation(y) even on the path where x has a value.

I believe this rule should be adjusted so it only fires if the argument to value_or() is sufficiently trivial, e.g. an integer literal, something that moving/copying does not require heap memory allocations, etc.

The above code would be a candidate for use of or_else in C++23, but for C++17/C++20, the if statement is in my opinion the better approach.

Thoughts/workarounds?

Hello @ajtribick,

Welcome to the community!

Thank you for this feedback. Indeed, the argument of value_or is always evaluated so the proposed solution in your case is not relevant.
There are ways to introduce lazy evaluation of arguments but this means adding code that would reduce the code readability. Which would be against the goal of the rule :slight_smile:
So I have created a ticket to fix that: CPP-4179.

Have a nice day,
Amélie

1 Like

Thanks a lot, much appreciated!

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.