Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is the address of a std::optional's value stable?

Tags:

Say I have a std::optional<T>. I reset and assign the value multiple times. Is the address of the value (when present) always the same for a given optional?

In other words:

#include <cassert>
#include <optional>
#include <string>

template<typename T>
auto test()
{
    auto opt = std::optional<T>{T{}};
    auto* ptr = &*opt;

    opt.reset();
    opt = T{};

    assert(ptr == &*opt); // Can this assert fail?
}

int main()
{
    test<int>();
    test<double>();
    test<std::string>();
    // ...
}

Does the standard guarantee the stability of the address of the value?

like image 837
Rumburak Avatar asked Feb 03 '18 19:02

Rumburak


People also ask

How efficient is std :: optional?

No, it's not as efficient. As you can see from the reference implementation it has to store, update and check an extra value.

Does STD optional allocate memory?

What's more, std::optional doesn't need to allocate any memory on the free store. std::optional is a part of C++ vocabulary types along with std::any , std::variant and std::string_view .

Is std :: optional a pointer?

The class template std::optional manages an optional contained value, i.e. a value that may or may not be present[1]. It is a great alternative for std::unique_ptr , or raw pointer, when used solely to express that a value is indeed optional.

What is Nullopt?

October 4th, 20216. C++17 introduced std::optional<T> which lets you augment the values of a type T with a bonus value known as std::nullopt which semantically represents the absence of a value. A std::optional which holds the value std::nullopt is known as empty. The basic operations on std::optional are.


1 Answers

Does the standard guarantee the stability of the address of the value?

From my point of view, it is unspecified whether the address is stable or not.

Formally, the standard only guarantees that there are no dynamic allocations for the object contained within std::optional and the containing object is stored as a part of std::optional:

23.6.3 Class template optional [optional.optional]

Any instance of optional at any given time either contains a value or does not contain a value. When an instance of optional contains a value, it means that an object of type T, referred to as the optional object’s contained value, is allocated within the storage of the optional object. Implementations are not permitted to use additional storage, such as dynamic memory, to allocate its contained value. The contained value shall be allocated in a region of the optional storage suitably aligned for the type T. When an object of type optional is contextually converted to bool, the conversion returns true if the object contains a value; otherwise the conversion returns false.

The actual storage mechanism is defined by a particular implementation, so, potentially, the address might change.

In practice, however, implementations will be using something like aligned_storage (see boost implementation) or union (as gcc does) and keep an address of the containing object the same.

like image 199
Edgar Rokjān Avatar answered Jan 14 '23 02:01

Edgar Rokjān