Some people don't know what lvalue or rvalue means. Think of a diagram with an large inverted "V", with the name of the variable at the point of the V. The leg pointing to the left is the lvalue, which is the memory address of where that variable is located in memory. The term lvalue probably comes from the assembly language days when a memory address was called its "location value", or lvalue.
The right leg of the V is what is stored at that memory location. This, too, likely comes from assembly language and stood for "register value", or rvalue.
Now take the definition of a variable:
int x;
and think of it as a bucket. The lvalue tells you where the bucket is located in memory, the rvalue tells you what's inside the bucket, and the data type specifier (e.g., the int keyword) tells you the size of the bucket...big enough to hold two bytes in this case. I developed this into The Bucket Analogy for my books, as it makes it easier to explain casts and pointers. For example:
int x;
float y = 35000;
x = y;
is a bad assignment because you're taking the contents of a 4 byte bucket and trying to pour it into a 2 byte bucket. You run the risk of overflowing and losing data. Changing the assignment to
x = (int) y;
using a cast is the correct thing to do even when the compiler doesn't flag it as an error.
Probably an H-Bomb-kill-an-ant post, but perhaps helps to explain what you're seeing.