views:

294

answers:

3

Could anyone explain the details in terms of rvalues, lvalues, PODs, and non-PODs the reason why the first expression marked below is not ok while the second expression marked below is ok? In my understanding both int() and A() should be rvalues, no?


struct A {};

int main()
{
  int i;
  A a;

  int() = i; //Not OK (error).
  A() = a; //OK.

  return 0;
}

+1  A: 

From http://stackoverflow.com/questions/906734/does-c-do-value-initialization-of-a-pod-typedef, which quotes the Standard:

The expression T(), where T is a simple-type-specifier (7.1.5.2) for a non-array complete object type or the (possibly cv-qualified) void type, creates an rvalue of the specified type, which is value-initialized

Therefore int() is an rvalue and can't be assigned to, as you saw in your first case.

A() would not be a simlle-type-specifyer and thus A() yields an lvalue

DVK
The link goes circularly to this page. §5.2.3 clearly specifies that T() is an rvalue whatever the type is.
Potatoswatter
Fixed the link - bug in FireFox(it didn't update address bar when switching tabs)
DVK
Even with the wrong link, the answer would be correct since the link pointed to a page with the link to a page with the link to a page ... with the quote. Too bad it wasn't tail-recursion. :-).
Alok
@DVK: `A` _is_ a simple type specifier.
James McNellis
A() is an rvalue, not an lvalue.
Roger Pate
+12  A: 
Roger Pate
C-specific, but still useful for C++ programmers to understand: http://stackoverflow.com/questions/2038414/lvalue-and-rvalue/2038427#2038427. (This is one area both languages fundamentally share, even though C++ is quite a bit more complicated with references and actually using the term "rvalue" which C doesn't anymore.)
Roger Pate
+1  A: 

In my understanding both int() and A() should be rvalues, no?

Correct, the epxression T() is always an rvalue for scalar and user-defined types T. As long as no const is involved, the expression T() is a modifiable rvalue, to be more precise.

Assignment involving scalar types requires a modifiable lvalue on the left hand side of the assignment operator. Since int() isn't an lvalue, you can't assign to int().

For user-defined types, assignment is a special member function, and member functions can also be called on rvalues (see §3.10 section 10). That's why A().operator=(a) is well formed.

FredOverflow