Boost logo

Boost :

Subject: Re: [boost] [operators] The future of Boost.Operators
From: Jeffrey Lee Hellrung, Jr. (jeffrey.hellrung_at_[hidden])
Date: 2013-04-25 00:33:08


On Wed, Apr 24, 2013 at 5:31 PM, Andrew Ho <helloworld922_at_[hidden]> wrote:

> I was assuming T was a given type:
>
> struct T : addable<T>
> {
> // ...
> }
>
> But I did some testing, and looks like the above code which normally should
> fail if operator+ returned a lvalue reference actually works with rvalues:
>
> struct T : boost::addable<T>
> {
> T(void)
> {
> std::cout << "T(): " << this << std::endl;
> }
>
> T(const T &val)
> {
> std::cout << "T(const T&): " << this << std::endl;
> }
>
> T(T &&val)
> {
> std::cout << "T(T&&): " << this << std::endl;
> }
>
> ~T(void)
> {
> std::cout << "~T(): " << this << std::endl;
> }
>
> T& operator +=(const T& op)
> {
> std::cout << this << " += " << &op << std::endl;
> return *this;
> }
> T& operator =(const T& op)
> {
> std::cout << this << " = const & " << &op << std::endl;
> return *this;
> }
>
> T& operator =(T&& op)
> {
> std::cout << this << " = && " << &op << std::endl;
> return *this;
> }
> };
>
> Output using VS2012 (displayed output in debug mode, but similar results
> occur in release mode):
>
> T &result = t1 + t2 + t3;
>
> T(): 0040FEDB
> T(): 0040FECF
> T(): 0040FEC3
> T(const T&): 0040FCD7
> 0040FCD7 += 0040FECF
> T(T&&): 0040FEAB
> ~T(): 0040FCD7
> 0040FEAB += 0040FEC3
>
> &result = 0040FEAB
>
> T result = t1 + t2 + t3;
>
> T(): 0035F9FF
> T(): 0035F9F3
> T(): 0035F9E7
> T(const T&): 0035F7FB
> 0035F7FB += 0035F9F3
> T(T&&): 0035F90F
> ~T(): 0035F7FB
> 0035F90F += 0035F9E7
> T(T&&): 0035F9DB
> ~T(): 0035F90F
>
> &result = 0035F9DB
>
> Is this just MS trying to be "clever", or are these results
> standard-compliant (and equally important, viable on all other rvalue-ref
> aware compilers)? If this is indeed expected behavior, then there shouldn't
> be any fuss over unsafe behavior at all, and the 4-overload version can be
> used without any problems (assuming we didn't miss any corner cases).
>

1) Please don't top-post.
2) I think my responses below still apply.
3) I suspect if you did T& x = f() + g(), where f() and g() are rvalues,
you'd be in trouble.

On Wed, Apr 24, 2013 at 3:41 PM, Jeffrey Lee Hellrung, Jr. <
> jeffrey.hellrung_at_[hidden]> wrote:
>
> > On Wed, Apr 24, 2013 at 1:36 PM, Andrew Ho <helloworld922_at_[hidden]>
> > wrote:
> >
> > > > Remind me how the 4-overload-version is unsafe, again?
> > >
> > > There's the potential for a user to assign a reference variable to an
> > > invalid temporary:
> > >
> > > T &var = a + b + c;
> > >
> >
> > Does operator+ return by value or by reference? If it returns by value,
> how
> > is the above possible? Is T a typedef or template parameter for a
> > const-qualified type in your example above?
> >
> > I am of the opinion this is a usage error (as is Daniel), but
> > > none-the-less, was previously valid because the operators returned by
> > > value.
> >
> >
> > Okay, now I'm really confused. I would think return-by-reference would
> > allow the above, but return-by-value would not.
> >
> > And how is this related to whether operator+'s parameters are by-value (1
> > overload) or by-reference (4 overloads)? I mean, other than the former
> > precluding return-by-reference, of course.
> >
> > Just as large a problem is that if this error does occur in real
> > > code (old or new), it can be difficult to identify.
> > >
> > > > A macro which globally switches the effect of all uses of
> > > Boost.Operators?
> > > > Let's avoid that.
> > >
> > > We will need at least the compiler feature check switch since rvalue
> > > references will cause compilers which don't support the feature fail.
> >
> >
> > Yeah, that's fine; you're switching on compiler features, and you're
> > switching to an objectively better implementation.
> >
> > Having a macro that switches *all* uses of Boost.Operators to either
> "safe"
> > or "fast" (whatever those mean) implies that you can't mix safe uses with
> > fast uses.
> >
> > After
> > > a little digging, the commutative operators will always need special
> > > handling since they directly use rvalue refs.
> > >
> > >
> > >
> > > On Wed, Apr 24, 2013 at 11:04 AM, Jeffrey Lee Hellrung, Jr. <
> > > jeffrey.hellrung_at_[hidden]> wrote:
> > >
> > > > On Tue, Apr 23, 2013 at 11:06 PM, Andrew Ho <helloworld922_at_[hidden]
> >
> > > > wrote:
> > > >
> > > > > Here's a thought about the direct use of r-value references vs.
> pass
> > by
> > > > > value
> > > > > argument:
> > > > >
> > > > > We are planning on providing a version which is supposed to support
> > > > > compilers
> > > > > without move semantics. However, these implementations are close
> to,
> > > > > perhaps
> > > > > even exactly identical to the code that would take advantage of
> move
> > > > > semantics
> > > > > via pass by value.
> > > > >
> > > > > Say we allowed a user-accessible define which would allow the
> > > programmer
> > > > to
> > > > > decide?
> > > > >
> > > >
> > > > A macro which globally switches the effect of all uses of
> > > Boost.Operators?
> > > > Let's avoid that.
> > > >
> > > > something like:
> > > > >
> > > > > // BOOST_HAS_RVALUE_REFS is a feature availability check
> > > > > // BOOST_UNSAFE_MOVE is user-definable override to use faster,
> unsafe
> > > > > version
> > > > > #if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_UNSAFE_MOVE)
> > > > > // use 4 overload version
> > > > > #else
> > > > > // use pass-by-value version
> > > > > #endif
> > > > >
> > > > > If the user is more concerned with safety over micro-optimizations,
> > the
> > > > > default behavior would resort to pass by value (good for backwards
> > > > > compatibility).
> > > > >
> > > >
> > > > Remind me how the 4-overload-version is unsafe, again?
> > > >
> > > > However, the user would have the option available to easily use the
> > > faster
> > > > > version if they deem it necessary.
> > > > >
> > > >
> > > > - Jeff
> > > >
> > > > _______________________________________________
> > > > Unsubscribe & other changes:
> > > > http://lists.boost.org/mailman/listinfo.cgi/boost
> > > >
> > >
> > >
> > >
> > > --
> > > Andrew Ho
> > >
> > > _______________________________________________
> > > Unsubscribe & other changes:
> > > http://lists.boost.org/mailman/listinfo.cgi/boost
> > >
> >
> > _______________________________________________
> > Unsubscribe & other changes:
> > http://lists.boost.org/mailman/listinfo.cgi/boost
> >
>
>
>
> --
> Andrew Ho
>
> _______________________________________________
> Unsubscribe & other changes:
> http://lists.boost.org/mailman/listinfo.cgi/boost
>


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk