I always wanted to know what is the real thing difference of how the compiler see a pointer to a struct (in C suppose) and a struct itself.
struct person p;
struct person *pp;
pp->age
, I always imagine that the compiler does: "value of pp + offset of atribute "age" in the struct".
But what it does with person.p
? It would be almost the same. For me "the programmer", p is not a memory address, its like "the structure itself", but of course this is not how the compiler deal with it.
My guess is it's more of a syntactic thing, and the compiler always does (&p)->age
.
I'm correct?
p->q
is essentially syntactic sugar for (*p).q
in that it dereferences the pointer p
and then goes to the proper field q
within it. It saves typing for a very common case (pointers to structs).
In essence, ->
does two deferences (pointer dereference, field dereference) while .
only does one (field dereference).
Due to the multiple-dereference factor, ->
can't be completely replaced with a static address by the compiler and will always include at least address computation (pointers can change dynamically at runtime, thus the locations will also change), whereas in some cases, .
operations can be replaced by the compiler with an access to a fixed address (since the base struct's address can be fixed as well).
Updated (see comments):
You have the right idea, but there is an important difference for global and static variables only: when the compiler sees p.age
for a global or static variable, it can replace it, at compile time, with the exact address of the age
field within the struct.
In contrast, pp->age
must be compiled as "value of pp + offset of age
field", since the value of pp can change at runtime.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With