Opened 12 years ago
Closed 12 years ago
#5303 closed Bugs (fixed)
assignment of boost::optional of const reference to a base works incorrectly
| Reported by: | Owned by: | Fernando Cacciola | |
|---|---|---|---|
| Milestone: | To Be Determined | Component: | optional |
| Version: | Boost 1.44.0 | Severity: | Problem |
| Keywords: | Cc: |
Description
#include <iostream>
#include <boost/optional.hpp>
class B
{
public:
virtual ~B() { }
virtual void foo() const = 0;
};
class D : public B
{
public:
virtual ~D() { std::cout << "D d-tor (" << this << ")" << std::endl; }
D() { std::cout << "D default c-tor (" << this << ")" << std::endl; }
D(const D& d) : B(d) { std::cout << "D copy c-tor (" << this << ")" << std::endl; }
virtual void foo() const { std::cout << "D::foo (" << this << ")" << std::endl; }
};
int main(int argc, char** argv)
{
D d;
B& b = d;
boost::optional<const B&> o;
o = d;
o->foo();
}
The above code compiles and crashes. The reason is the assignment o = d. Apparently, the assignment operator that gets called copies d (since it's passed by value), takes its reference and then the local copy gets destroyed, in which case o->foo() is called on an invalid object.
If the definition of o is changed to boost::optional<B&> the code doesn't compile (I haven't checked the whole code of boost::optional, but I assume this is intentional - in which case it should be the same in the const reference case).
Alternatively, assigning o = b instead of o = d works fine (because b is const B&) which is the same type as the template argument of the optional.

This was fixed as a side-effect of [67020]. The fix is in 1.46.0