OneZero
OneZero

Reputation: 11914

Why is returned object an rvalue?

class A {}

A foo() {
  A a;
  // some work
  return a;
}

Here it returns an instance of A, and I saw many readings saying that this returns a rvalue.

My confusion is, since it's perfectly legit to do A b; a = b;, the variable a seems to be an lvalue. So why does it become rvalue when it's the returned one?

Upvotes: 0

Views: 149

Answers (2)

Cheers and hth. - Alf
Cheers and hth. - Alf

Reputation: 145419

There is no such thing as an rvalue object.

Rvalue and lvalue refers to expressions.

One expression that refers to an object can be an rvalue, while another that refers to the same object can be an lvalue.


Originally "lvalue" referred to any expression that could be on the left hand side of C's =, while "rvalue" was any expression that could only be on the right side. Since then C++ has acquired const and references, and things have got complicated. But the early C view of things is useful to understand this.


Regarding …

the variable a seems to be an lvalue. So why does it become rvalue when it's the returned one?

Well, the variable in itself is not an lvalue. The expression a is an lvalue. And the function does not return the variable: it returns the variable's value.

So, as I understand it there are two misconceptions involved in the question:

  • The idea that lvalue/rvalue is about objects. It's about expressions.

  • The idea that A foo() { return... } return a reference to an object (as in e.g. Java). It returns a value.

Upvotes: 4

GreatAndPowerfulOz
GreatAndPowerfulOz

Reputation: 1775

An lvalue is an expression that refers to a memory location and allows us to take the address of that memory location via the & operator. An rvalue is an expression that is not an lvalue.

See here http://thbecker.net/articles/rvalue_references/section_01.html

In your example, you're returning a copy of a stack allocated instance. But that is likely also on the stack and is a 'temporary copy', hence you cannot take the address of it. Hence it's not an lvalue, therefore it's an rvalue

Upvotes: 0

Related Questions