Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing pointers by value or by const ref?

Tags:

c++

In a nutshell, is it better to pass a pointer by value or by const reference?

I wrote a simple function to explore:

void foo(int* v) { std::cout << *v << endl; }

versus

void foo(int* const& v) { std::cout << *v << endl; }

I tried to look at the assembly generated but I'm not particularly good at assembly so I'm not sure I understand the difference. But there is a difference. In the first case, we get:

pushq   %rbp
pushq   %rbx
subq    $8, %rsp
movl    (%rdi), %esi
movl    std::cout, %edi
call    std::basic_ostream<char, std::char_traits<char> >::operator<<(int)

In the const& case, we get one more operation:

pushq   %rbp
pushq   %rbx
subq    $8, %rsp
movq    (%rdi), %rax
movl    std::cout, %edi
movl    (%rax), %esi
call    std::basic_ostream<char, std::char_traits<char> >::operator<<(int)

What does that difference mean (three mov's instead of two) and what is the implication of that? (Basically, I have a struct Foo<T> where T could be a raw pointer or not, and am wondering if my function bar(const T&) should instead be bar(typename boost::call_traits<T>::type). ).

like image 612
Barry Avatar asked Mar 22 '26 21:03

Barry


2 Answers

Pass pointers by value, unless you need reference semantics.

Passing by reference is almost certainly implemented by passing a pointer. You'd pass the same amount of data as the pointer itself, but introduce an extra level of indirection, so it's likely to be less efficient than passing by value.

Having said that, the difference is likely to be tiny; so for generic code it's simpler to pass by const reference, unless you really need to micro-optimise at the level of single instructions. If you do then, as you say, boost::call_traits can help.

like image 163
Mike Seymour Avatar answered Mar 25 '26 13:03

Mike Seymour


Passing pointers by reference will do the following:

Address: 0x00  -  42   (int)
Address: 0x11  -  0x00 (int*)
Address: 0x22  -  0x11 (int* const&)

This is basically what the compiler will generate for int* const&. Implementation wise, it will likely end up being int**.

So passing pointers by value will end up being more efficient, as you will copy the address of the int directly, without overhead of the third row.

like image 33
ScarletAmaranth Avatar answered Mar 25 '26 13:03

ScarletAmaranth



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!