DEV Community

Pierre Gradot
Pierre Gradot

Posted on β€’ Edited on

3

std::optional from C++17 vs custom type for optional value

C++17 has introduced a very useful template class, std::optional:

The class template std::optional manages an optional contained value, i.e. a value that may or may not be present.

I have been using this feature a lot since 2017, even for a simple optional integer. Today, I got curious: is this template type effective compared to an equivalent type that I would write myself to achieve the same behavior?

Good question, thank you πŸ˜†

Let's try to write some code and use Compiler Explorer to compare both solutions: std::optional vs custom type for optional value.

First, let's define two equivalent types:

#include <optional>

using StdOptionalInt = std::optional<int>;

struct CustomOptionalInt {    
    bool has_value;
    int value;
};
Enter fullscreen mode Exit fullscreen mode

Then, let's write two functions that test if the value is available and return either this value (if available) or a default value (if not available):

int getStdOptional(const StdOptionalInt& o) {
    return o.has_value() ? o.value() : 0;
}

int getCustomOptional(const CustomOptionalInt& o) {
    return o.has_value ? o.value : 0;
}
Enter fullscreen mode Exit fullscreen mode

Finally, compile the code with Compiler Explorer and compare the output assembly codes (you can try by yourself here):

with_compiler_explorer

Yeah! πŸ˜ƒ The 2 functions generate the same assembly code. There is no difference of performance. Notice the static assertion at the end of the source code: because the code compiles, it means the footprint are the same. The behavior is the same with gcc and clang for x86-64.

As a conclusion, std::optional is as efficient as a custom type to represent an optional integer value. Don't implement your own type, simply use the standard type. You may even get better performance using std::optional, as explained on cppreference:

As opposed to other approaches, such as std::pair<T,bool>, optional handles expensive-to-construct objects well and is more readable, as the intent is expressed explicitly.


By the way, if you happen to speak French:

  • I wrote an article to explain to how to use std::optional.
  • I made a video to present Compiler Explorer.

Please leave your appreciation by commenting on this post!

It takes one minute and is worth it for your career.

Get started

Top comments (2)

Collapse
 
sandordargo profile image
Sandor Dargo β€’

Stunning that the generated code is the same. Have you had a look into one od the standard implementations?

github.com/gcc-mirror/gcc/blob/mas...

Collapse
 
pgradot profile image
Pierre Gradot β€’ β€’ Edited

To be honest, I wasn't surprised. I was not expecting the exact same code but I was expecting something similar, for various reasons:

  1. has_value() is just about returning a bool. No reason to cost more than a simple access to member variable.
  2. value() is just a test to decide to return the value or throw an exception. Nothing fancy here.

We may expect the exception to cost a more than a simple access to a member variable. So why ?

This leads me to reason 3. Over the years (and hours spent in Compiler Explorer, you definitively must use it!), I have learned something important: modern compilers are amazing at optimizing code. Way much better that you and me.

And here, take a better look at the code: it tests if the std::optional has a value and get the value conditionally. The compiler then know the exception cannot be thrown and optimizes that out.

Change the code and get a completely different result:

int getStdOptional(const StdOptionalInt& o) {
    return o.value();
}
Enter fullscreen mode Exit fullscreen mode

This generates all the code to handle the exception and it's a lot a code.

I something take a look at the source of standard features. I simply to a CTRL+click in my IDE. std::optional seems crazy but it does much more than my custom type. It is made by and for the standard library developers. And this leads me to reason 4 : these developers are way better than you and me to create powerful, flexible, easy-to-use, robust code ;)

AWS Security LIVE!

Tune in for AWS Security LIVE!

Join AWS Security LIVE! for expert insights and actionable tips to protect your organization and keep security teams prepared.

Learn More

πŸ‘‹ Kindness is contagious

Engage with a sea of insights in this enlightening article, highly esteemed within the encouraging DEV Community. Programmers of every skill level are invited to participate and enrich our shared knowledge.

A simple "thank you" can uplift someone's spirits. Express your appreciation in the comments section!

On DEV, sharing knowledge smooths our journey and strengthens our community bonds. Found this useful? A brief thank you to the author can mean a lot.

Okay