Is use of empty std::optional<string> UB or not?

Viewed 1196

The following code:

    std::optional<std::string> so;
    std::cout << so->size() << std::endl;
    std::cout << so.has_value();

outputs:

   0
   0  

My question is whether its safe to call : so->size() on an empty optional. I used clang sanitizer, but it didnt report any UB in above code.

3 Answers

Using operator-> on an empty std::optional is Undefined Behavior, regardless of what type T is in std::optional<T>.

According to cppreference on std::optional<T>::operator-> :

The behavior is undefined if *this does not contain a value.

Quoting the current C++ working draft

20.6.3.6 Observers [optional.observe]

constexpr const T* operator->() const;
constexpr T* operator->();

Preconditions: *this contains a value.


Then:

16.3.2.4 Detailed specifications [structure.specifications]

Preconditions: the conditions that the function assumes to hold whenever it is called; violation of any preconditions results in undefined behavior.

Thus, it's undefined behavior.

You're calling the default optional constructor (1 in that link), which...

  1. Constructs an object that does not contain a value.

When you go to dereference...

The behavior is undefined if *this does not contain a value.

Which in your case it doesn't. So yes, you have UB.

Related