Link bound xvalue extended or not?

There seem to be some confusion and differences between compilers regarding this issue:

http://social.msdn.microsoft.com/Forums/vstudio/en-US/3c754c4e-5471-4095-afae-795c1f411612/rvalue-refs-extended-lifetime-inconsistent-with-gccstandard

According to this post:

What are rvalues, lvalues, xvalues, glvalues, and prvalues?

Xvalues ​​are r values ​​(along with prvalues), and the standard states:

The second context is when the binding is tied to a temporary one. temporary, to which the link is attached, or temporary, which is the full object of the subobject to which the link is attached, is preserved for the duration of the link, with the exception of:

However, there are reports that dispute this:

Do rvalue links let you spoof links?

What is an example of the difference in allowed usage or behavior between xvalue and prvalue objects for NON-POD objects?

Can someone clarify the problem. Is MSVC correct?

+4
source share
1 answer

Xvalues ​​may be r values, but this does not mean that they are temporary. The extension of temporary lifetimes is due to the fact that they are temporary, and not their price category.

I intentionally try not to know the order in which operators are processed (in this way, I force myself to write code that either uses explicit brackets or does not care about order). Your specific example adder code reproduced here really cares:

 template <class T> struct addable { friend T operator +( const T& lhs, const T& rhs ) { return std::move(T(lhs) += rhs); } friend T operator +( const T& lhs, T&& rhs ) { return std::move(T(lhs) += std::move(rhs)); } friend T&& operator +( T&& lhs, const T& rhs ) { return std::move(lhs += rhs); } friend T&& operator +( T&& lhs, T&& rhs ) { return std::move(lhs += std::move(rhs)); } }; 

If the + operator is executed from right to left, then t1 + t2 + t3 will work until t1 + (t2 + t3) . t2 + t3 will cause the first overload, thereby creating a temporary overload, which will give t1 + temp . Since the time reference will preferably be associated with a reference to the value of r, this expression will cause a second overload, which will also return a temporary one.

However, if the + operator works from left to right, you get (t1 + t2) + t3 . This gives us temp + t1 , which causes the problem. This will cause a third overload. The lhs parameter of this function is T&& , a reference to a temporary one. You are returning the same link. This means that you returned the link to a temporary one. But C ++ does not know this; all he knows is that you return a link to something.

This "something", however, must be destroyed after the final expression (assignment of a new variable, either a value type or a reference type). Remember: C ++ does not know that this function will return a link to the first parameter. Thus, he does not know that the lifetime of the temporary passed to the functional operand should be extended to the lifetime in which the returned link is stored.

By the way, this is why expression trees can be dangerous with auto and such hiding ones. Since the created internal temporary records cannot be saved by new temporary or references stored in different objects. C ++ simply has no way to do this.

So who is right depends on the order in which the operators are allowed. However, I prefer my decision: do not rely on these corners of the language and just go around them. Stop returning T&& from these overloads and just move the value to a temporary one. Thus, it is guaranteed to work correctly, and you do not need to constantly check the standard to make sure your code works.

In addition, as a third-party, I would find it somewhat rude for the + operator to actually change one of the parameters.

However, if you insist on knowing who is right, this is GCC. From section 5.7, p1:

Additive operators + and - group from left to right.

So yes, this should not work.

Note. Visual Studio allows T &r2 = t1 + t2 + t3; compile as a (very annoying) language extension. You must have received a warning from him.

+3
source

Source: https://habr.com/ru/post/1492535/


All Articles