For example,
int x = 10;
We know that identifier x
acts like a label which refers object that stores the value 10
. But why can't &x
also be called as a label which refers the same object? &x
is an address value of the whole int
object which stores the value 10
. So I think identifier x
and &x
has no difference in playing a role as a label of the object. Therefore, I believe this gives a good reason to say that &x
is an lvalue
. Because according to ISO C11 6.3.2.1, it says that
lvalue is an expression that potentially designates an object.
But why isn't the pointer value &x
an lvalue
?
Because &x isn't a label, it's a pointer to a labeled value.
To help you understand why this is important, I'm going to give an explanation of the different types of references:
labels - also called 'aliases' or 'names', they identify some value or object. in a dynamically-typed language, the value or object they identify can change; whereas in a statically-typed language, it stays the same. an example of a label-type reference in C would be int x;
pointer - a pointer identifies the address of some value or object. this is useful for implementing aliasing (having multiple references to the same object). an example of a pointer-type reference in C would be int *x;
or &x
handle - a handle is a unique identifier (usually an integer) for some value or object. like pointers, they allow for aliasing; but a handle cannot be dereferenced like a pointer. This is extremely useful because it can be used to hide the underlying implementation of a data structure and allow for a memory manager to safely rearrange memory (eg. defragmentation) to improve cache coherency and boost performance. an example of a handle-type reference in C would be the int
value returned by POSIX open
function.
Off-topic: In Golang, when you try to assign to the member of a pointer-type object, it's automatically dereferenced; so there's no need for a ->
operator. For vec2 *v
, v.x
would be interpreted as v[0].x
.