How expensive is it to perform the dereference operation on a pointer?
I can imagine that the memory transfer is somehow proportional to the object size, but I want
It depends on what you do with the dereferenced pointer. A mere dereference operation does nothing in itself. It just gets an lvalue of type T which represents your object, if your pointer is a T*
struct a {
int big[42];
};
void f(a * t) {
// does nothing. Only interesting for standard or compiler writers.
// it just binds the lvalue to a reference t1.
a & t1 = *t;
}
If you actually get the value out of that object denoted by the lvalue returned by the dereference operation, the compiler has to copy the data the object contains. For a simple POD, that is just a mere memcpy:
a aGlobalA;
void f(a * t) {
// gets the value of of the object denoted by *t, copying it into aGlobalA
aGlobalA = *t;
}
My gcc port outputs this code for f:
sub $29, $29, 24 ; subtract stack-pointer, creating this frame
stw $31, $29, 20 ; save return address
add $5, $0, $4 ; copy pointer t into $5 (src)
add $4, $0, aGlobalA ; load address of aGlobalA into $4 (dst)
add $6, $0, 168 ; put size (168 bytes) as 3rd argument
jal memcpy ; call memcpy
ldw $31, $29, 20 ; restore return address
add $29, $29, 24 ; add stack-pointer, destroying this frame
jr $31
Optimized machine code would use in-line code instead of a call to memcpy, but that's really just an implementation detail. What is important is, that merely *t isn't executing any code, but accessing the value of that object actually needs to copy it.
Would we have to do with a type having a user defined copy assignment operator, affairs are more complex:
struct a {
int big[42];
void operator=(a const&) { }
};
The code for the same function f now looks like:
sub $29, $29, 8
add $29, $29, 8
jr $31
Hah. But it wasn't such a surprise, wasn't it? After all, the compiler is supposed to call our operator=, and if it does nothing, the whole function also does nothing!
I think the conclusion we can draw is, it all depends on how the returned value of operator* is used. If we have just a pointer that we dereference, we see above that the code generated largely depends on the circumstances. I haven't showed how it behaves if we dereference a class type having overloaded operator* . But essentially, it's just behaving like we saw with operator=. All measurements were done with -O2, so the compiler properly inlined calls :)