lvalue and assignment to temporary object

S

subramanian100in

Consider the following:
int x;
int y;
int z;
(x+y) = z;

For this statement, I get the following error with g++ compiler:
error: non-lvalue in assignment

Suppose I have a class Test and x, y, z are objects of type Test.
Suppose I have
Test Test::eek:perator+(const Test& ref);
Test operator+=(Test lhs, Test rhs);

Given this, the following are accepted by g++:
(x+y) = z;
(x+y) += z;

My question:
Is (x+y) an lvalue ?

I thought, x+y being a temporary object, we cannot take its address
and so not an lvalue. However the compiler accepts it on the left hand
side of the assignment operator. I am unable to understand this.

Kindly clarify

Thanks
V.Subramanian
 
S

Sarath

Consider the following:
        int x;
        int y;
        int z;
      (x+y) = z;

For this statement, I get the following error with g++ compiler:
error: non-lvalue in assignment

Suppose I have a class Test and x, y, z are objects of type Test.
Suppose I have
Test Test::eek:perator+(const Test& ref);
Test operator+=(Test lhs, Test rhs);

Given this, the following are accepted by g++:
(x+y) = z;
(x+y) += z;

My question:
Is (x+y) an lvalue ?

I thought, x+y being a temporary object, we cannot take its address
and so not an lvalue. However the compiler accepts it on the left hand
side of the assignment operator. I am unable to understand this.

Kindly clarify

Thanks
V.Subramanian

In my understanding temporary object concept is compiler's internal
matter. It will generated if destructor need to called.

For the classes it will create Temporary objects because you have
constructed something and it should be destructed on exiting from the
class. It's C++ compiler's duty to put corresponding dtor call. In the
case of primitive data type there's nothing to do. It deosn't require
any temp objects. when the expression with primitive data type
evaluated, it will seek for a valid memory location to store data
(variables) thus (x+y) = z not constitutes a valid
expression(primitive type).

Regards,
Sarath
 
J

James Kanze

Consider the following:
int x;
int y;
int z;
(x+y) = z;
For this statement, I get the following error with g++ compiler:
error: non-lvalue in assignment
Correct.

Suppose I have a class Test and x, y, z are objects of type Test.
Suppose I have
Test Test::eek:perator+(const Test& ref);
Test operator+=(Test lhs, Test rhs);
Given this, the following are accepted by g++:
(x+y) = z;
(x+y) += z;
My question:
Is (x+y) an lvalue ?

No. But the = here isn't really an operator, either; it's more
a particular syntax of a function call. (Overloaded "operators"
are only partially operators---they have the syntax of
operators, but semantics of a function call.)

Since you can call a member function on an lvalue, the above is
legal.
I thought, x+y being a temporary object, we cannot take its
address and so not an lvalue.

That would be too simple. x+y is a temporary object (an
rvalue), and *you* cannot take its address. rvalues of class
types do have addresses, however, and the compiler can get at
the address if it needs to, for example to call a member
function.

(Technically, you cannot take its address is only partially
true. You can not apply the built-in operator & on it, since
the built-in operator & requires an lvalue, which it is not. If
the class overloads operator&, however, we're back to the above
rule: the overloaded operator is a function call of a member
function, which is legal.)
However the compiler accepts it on the left hand side of the
assignment operator. I am unable to understand this.

It is confusing. There are several different concepts involved
simultaneously, and there is also the fact that rvalue means
something different for class types than for non-class types.
 
J

James Kanze

On Dec 21, 3:18 pm, "(e-mail address removed), India"

[...]
In my understanding temporary object concept is compiler's internal
matter. It will generated if destructor need to called.

Conceptually, there's nothing wrong with imagining everything as
being an object (in the C++ sense of occupying memory and having
an address). For non-class types, however, there's almost
nothing you can do to reveal the underlying object, and of
course, the compiler is free to optimize it out if doing so
doesn't change the semantics of the generated code.
For the classes it will create Temporary objects because you
have constructed something and it should be destructed on
exiting from the class.

It's still a question of optimization. I would imagine (hope?)
that in a lot of uses of a temporary std::complex<double>, for
example, no "object" ever really exists.

If for any reason, the compiler is incapable of inlining any of
functions called on a temporary of class type (including the
constructor and the destructor), then it will almost certainly
have to allocate it as if it were an object, since it needs an
address to pass as the hidden argument which will become the
this pointer. If the compiler is capable of inlining all of the
called functions, however, it may very well determine that no
object is necessary.
It's C++ compiler's duty to put corresponding dtor call. In
the case of primitive data type there's nothing to do. It
doesn't require any temp objects.

What about in the case of:

int const& i = 3 ;
std::cout << &i << std::endl ;

What is the address you output, if not the address of a
temporary object of primitive data type?

The issue is not simple. We discussed it rather at length
during standardization (around 1993-1995); there were a number
of suggestions for a simpler, more coherent specification, but
in the end, they all ended up not supporting something that we
considered essential.
When the expression with primitive data type evaluated, it
will seek for a valid memory location to store data
(variables) thus (x+y) = z not constitutes a valid
expression(primitive type).

It's not a valid expression because the standard says it's not.
It's really hard to say more than that.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,772
Messages
2,569,593
Members
45,111
Latest member
VetaMcRae
Top