I've always been told that we should not pass POD by reference. But recently I've discovered that a reference actually takes no memory at all.
So why do we choose to write:
void DoSomething(int iNumber);
instead of:
void DoSomething(const int& riNumber);
is it not more efficient?
Actually in this case (using int) passing by value is probably more efficient, since only 1 memory-read is needed instead of 2, to access the passed value.
Example (optimized using -O2):
int gl = 0;
void f1(int i)
{
gl = i + 1;
}
void f2(const int& r)
{
gl = r + 1;
}
int main()
{
f1(1);
f2(1);
}
Asm
.file "main.cpp"
.text
.p2align 2,,3
.globl __Z2f1i
.def __Z2f1i; .scl 2; .type 32; .endef
__Z2f1i:
LFB0:
pushl %ebp
LCFI0:
movl %esp, %ebp
LCFI1:
movl 8(%ebp), %eax
incl %eax
movl %eax, _gl
leave
ret
LFE0:
.p2align 2,,3
.globl __Z2f2RKi
.def __Z2f2RKi; .scl 2; .type 32; .endef
__Z2f2RKi:
LFB1:
pushl %ebp
LCFI2:
movl %esp, %ebp
LCFI3:
movl 8(%ebp), %eax
movl (%eax), %eax
incl %eax
movl %eax, _gl
leave
ret
LFE1:
.def ___main; .scl 2; .type 32; .endef
.p2align 2,,3
.globl _main
.def _main; .scl 2; .type 32; .endef
_main:
LFB2:
pushl %ebp
LCFI4:
movl %esp, %ebp
LCFI5:
andl $-16, %esp
LCFI6:
call ___main
movl $2, _gl
xorl %eax, %eax
leave
ret
LFE2:
.globl _gl
.bss
.align 4
_gl:
.space 4
Not passing PODs by reference seems like a too general rule. PODs can be huge, and passing references to it would be worth. In your particular case, an int
is the same size than the pointer that most -if not all- implementations use in the background to actually implement references. There is no size difference between passing an int
or a reference, but now you have the penalty of an extra level of indirection.
Passing by reference is passing by pointer in disguise.
With small data, it can be faster to access it as values rather than having to deference the pointer several times.
Because it is a meaningless efficiency gain 99.999% of time, and it changes the semantics. It also prevents you from passing in a constant value. For example:
void Foo(int &i) { }
Foo(1); // ERROR!
This would work however:
void Foo(const int &i) { }
Foo(1);
Also, it means that the function can modify the value of i such that it is visible to the caller, which may well be a bad thing (but again, you could certainly take a const reference). It comes down to optimizing the parts of your program where it matters and making the semantics of the rest of the code as correct as possible.
a reference actually takes no memory at all.
Not sure who told you that, but it's not true.
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