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