Opened 13 years ago

Closed 12 years ago

#3395 closed Bugs (fixed)

Assignment to optional is not possible if operator& is overriden

Reported by: Andrey Semashev Owned by: Fernando Cacciola
Milestone: Boost 1.41.0 Component: optional
Version: Boost 1.40.0 Severity: Problem
Keywords: optional assignment Cc:

Description

The assignment operator for optional< T > uses T::operator& to dispatch the call between assign_expr functions. This dispatch breaks if the T::operator& returns something else than T*. This is the case with ATL types, such as CComBSTR.

The suggested fix is to replace call to operator& with addressof. Please, find the attached patch against the 1.40 release.

Attachments (2)

optional.hpp.patch (789 bytes ) - added by Andrey Semashev 13 years ago.
An updated fix that also optimises away copying the assignment argument
zd (1.5 KB ) - added by Ralf W. Grosse-Kunstleve 12 years ago.
proposed patch for review

Download all attachments as: .zip

Change History (12)

comment:1 by Andrey Semashev, 13 years ago

BTW, I just now noticed that the assignment operator accepts its argument by value. It may be worth to accept it by const reference, as the operator is not only called for in-place factories but also for other types. For example:

struct MyString
{
    MyString(std::string const&);
};

std::string str = "Hello";
boost::optional< MyString > opt;

opt = str; // here a needless copy of str will be constructed

I'm attaching an updated patch that fixes this, too.

by Andrey Semashev, 13 years ago

Attachment: optional.hpp.patch added

An updated fix that also optimises away copying the assignment argument

comment:2 by Andrey Semashev, 12 years ago

(In [67020]) Refs #3395. Optional construction and assignment now works correctly for types with overridden operator&. Also silenced some GCC warnings about broken strict aliasing rules.

by Ralf W. Grosse-Kunstleve, 12 years ago

Attachment: zd added

proposed patch for review

in reply to:  2 ; comment:3 by Ralf W. Grosse-Kunstleve, 12 years ago

The current optional.hpp leads to gcc 3.2 warnings (Redhat 8.0). It is easily fixed with the proposed patch I attached a minute ago. Is this OK to commit? -- It is tested already locally on a large number of platforms.

in reply to:  3 comment:4 by Steven Watanabe, 12 years ago

Replying to rwgk:

The current optional.hpp leads to gcc 3.2 warnings (Redhat 8.0). It is easily fixed with the proposed patch I attached a minute ago. Is this OK to commit? -- It is tested already locally on a large number of platforms.

This looks good to me.

comment:5 by anonymous, 12 years ago

Looks good to me as well. Please go ahead and commit.

comment:6 by Andrey Semashev, 12 years ago

Perhaps, the patch should also take into account GCC versions prior to 3.2? I really don't know since which version may_alias has become available.

comment:7 by Ralf W. Grosse-Kunstleve, 12 years ago

I checked in my patch as svn trunk rev. [67109] before seeing comment 6.

Is anyone still using a gcc before 3.2? Even 3.2 is ancient now (released 2002). It is the oldest gcc I have, i.e. I couldn't test with any older versions.

comment:8 by Andrey Semashev, 12 years ago

That's ok, I've updated your change with a check for earlier GCC versions. Try with the updated version.

comment:9 by anonymous, 12 years ago

It ran without a problem in our nightly builds (24 platforms). Thanks!

comment:10 by Andrey Semashev, 12 years ago

Resolution: fixed
Status: newclosed

(In [67183]) Merged changes from trunk. Fixes #3395. Also updates swap behavior: if default constructor has no-throw guarantee, swap will use it to provide no-throw guarantee itself. operator>> behavior changed slightly so that the stream is not accessed when unrecognized character sequence is detected. The stream is marked with failbit in such a case.

Note: See TracTickets for help on using tickets.