$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
From: Joe Gottman (jgottman_at_[hidden])
Date: 2005-02-16 20:09:51
"Fernando Cacciola" <fernando_cacciola_at_[hidden]> wrote in message 
news:cuvnj8$urr$1_at_sea.gmane.org...
>
> The correct fix along Joe's initial proposal would be:
>
> void assign(optional_base const& rhs)
> {
>  if (is_initialized)
>  {
>    if ( rhs.is_initialized )
>         get_impl() = rhs.get_impl();
>    else destroy();
>  }
>  else
>  {
>    if ( rhs.is_initialized )
>      construct(rhs.get_impl());
>  }
> }
>
> AFAICS, this code is as safe aliasing-wise as it can be (it handles not 
> only the trivial case of this==&rhs but also any other deeper aliasing 
> issues)
>
> If no voice is raised I'll proceed with this fix.
   While you're at it, you should also fix your other versions of assign(). 
For instance,  consider this flavor of self-assignment:
    optional<string> x("foo");
    x = *x; // Assign to x from dereferenced x.
This calls the following version of assign:
 void assign ( argument_type val )
      {
        destroy();
        construct(val);
      }
Thus the code destroys *x, then attempts to assign to *x by dereferencing a 
pointer to uninitialized memory, resulting in undefined behavior.  This is 
should be rewritten as
void assign(argument_type val)
{
    if (is_initialized) {
        get_impl() = val;
    } else {
        construct(val);
    }
}
Joe Gottman