Boost logo

Boost :

From: Joe Gottman (jgottman_at_[hidden])
Date: 2005-02-14 20:35:31

   I just discovered that optional<T> is not safe under self-assignment.
Consider the following code fragment:

    boost::optional<long> x(1); //At this point x is initialized and *x == 1
    x = x; //x should be unchanged, but instead x is now uninitialized

Optional's assignment operator looks like

optional& operator= ( optional const& rhs )
        this->assign( rhs ) ;
        return *this ;

and assign is defined by

void assign ( argument_type val )

Thus, if (this == &rhs) in operator=(), any value held by rhs will be

I can see two possible fixes for this. the first is to put an "if (this !=
&rhs) " around the call to assign in operator=(). This is simplest, but it
slows the code down in order to protect against a very rare situation. The
other is to rewrite assign as follows:

void assign(argument_type val)
    if (m_initialized) {
        get() = val; // call assignment operator
    } else {
        construct(val); //call copy constructor
    return *this;

This makes optional self-assignment safe. It has the added advantage that
is T's assignment operator has the strong exception safety guarantee, so
does optional<T>'s assignment operator. It has the disadvantage of making
optional depend on both assignment operator and copy constructor to copy,
but very few classes have a copy constructor but don't have an assignment

Joe Gottman


Boost list run by bdawes at, gregod at, cpdaniel at, john at