Sign in to follow this  
discman1028

passing a dereferenced ptr by reference

Recommended Posts

Just for curiousity's sake: are compilers smart enough to ignore the dereferencing cost in the following case?
void foo( object& anObj )
{
 ...
}

int main()
{

   object* obj = new obj;
   foo( *obj );  // Will a compiler avoid this dereference?

   return 0;

}



I do this often.. if passing a pointer by value is faster, I'd like to know. Thanks.

Share this post


Link to post
Share on other sites
I don't know, but what does it matter? A reference is only a de-referenced pointer anyway.

I can't imagine that if the compiler did ignore it that it would run much faster. I mean, how long does de-referencing take? I wouldn't think it takes very long.

Share this post


Link to post
Share on other sites
Quote:
Original post by Endar
I can't imagine that if the compiler did ignore it that it would run much faster. I mean, how long does de-referencing take? I wouldn't think it takes very long.


Well, everything's relative.. just curious, I guess. I mean, dereferencing involves fetching a value (potentially) from the heap, and passing it as an argument *might* put it on the stack (but I don't think so). If I passed a ptr by value, that heap fetch could be deferred until inside the function. More importantly, the dereferenced variable would never have to be pushed onto the stack. Babble babble...

But as I say, I don't know if it gets passed around / pushed around before its address is simply taken and given to the function, as a reference.

EDIT:

Quote:
Original post by Endar
A reference is only a de-referenced pointer anyway.


I thought a reference was a pointer that hasn't been fetched / de-referenced yet (aren't "fetched" / "de-referenced" synonymous?), but using a reference avoids the ugly syntax of de-referencing.

Share this post


Link to post
Share on other sites
I would assume that it would never dereference the pointer since when passing by reference all it should care about is the address of the object. Just to make sure I made a little test and checked the assembly output using g++ -S test.cpp


void foo( int& bob )
{
bob = 5;
}

int main()
{
int* obj = new int;
foo( *obj );

return 0;
}




If I am reading this gcc assembly output correctly, then it just passes along the address it got from new. Scroll down to see the part.


.file "dref.cpp"
.text
.align 2
.globl __Z3fooRi
.def __Z3fooRi; .scl 2; .type 32; .endef
__Z3fooRi:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %eax
movl $5, (%eax)
popl %ebp
ret
.def ___main; .scl 2; .type 32; .endef
.align 2
.globl _main
.def _main; .scl 2; .type 32; .endef
_main:
pushl %ebp
movl %esp, %ebp
subl $24, %esp
andl $-16, %esp
movl $0, %eax
addl $15, %eax
addl $15, %eax
shrl $4, %eax
sall $4, %eax
movl %eax, -8(%ebp)
movl -8(%ebp), %eax
call __alloca
call ___main


; here is where we care about
movl $4, (%esp)
call __Znwj ; function called to allocate memory
movl %eax, -4(%ebp) ; puts address in local variable's stack position
movl -4(%ebp), %eax ; puts that address in eax
movl %eax, (%esp) ; puts the address on stack for function call,
; the actual object is never accessed
call __Z3fooRi ; calls foo function
movl $0, %eax
leave
ret
.def __Znwj; .scl 3; .type 32; .endef



Share this post


Link to post
Share on other sites
C++ References are just less syntaxically abrasive const pointers.

Well, I take that back. There's some wonky quirkish things things specified in the standard about by-value returns and things related to storage IIRC (that lead to defined behavior in situations where pointers would not), but in this situation, the exact same mechanics will be used in both situations.

The only affect either should have on the outputted code should be name mangling. Rest assured, unless your compiler is a total hack job by 1985's standards, references and const pointers should behave identically in performance.

Share this post


Link to post
Share on other sites
Quote:
Original post by MaulingMonkey
C++ References are just less syntaxically abrasive const pointers.

Well, I take that back. There's some wonky quirkish things things specified in the standard about by-value returns and things related to storage IIRC (that lead to defined behavior in situations where pointers would not), but in this situation, the exact same mechanics will be used in both situations.

The only affect either should have on the outputted code should be name mangling. Rest assured, unless your compiler is a total hack job by 1985's standards, references and const pointers should behave identically in performance.


Well yes, but I assume the original question was really "will the code emitted for main() include a useless dereference (to find the pointed-at value) followed immediately by a re-reference (to create the machine-level implementation of the reference)?"

In which case, no. Even I could have implemented the relevant optimization, *before* I took that optimizing-compilers course in university.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this