Search code examples
cpointerslvalue

Why can't pointer value be a good label to refer object in memory space?


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?


Solution

  • 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.