Re: Copy vs. const reference function argument
 
Przemyslaw Koprowski wrote:
Hi all,
Is there any difference between the following:
foo someFunction(const foo& A)
{
    foo B(A);
    // do sth. to B
    return B;
}
and
foo someFunction(foo A)
{
    // do sth. to A
    return A;
}
I think there is none (a short test on gcc, with all 
optimalizations on, seems to support this), but if 
there is any I would like to know.
Semantically, there's a difference. When you pass by reference, the 
compiler has to preserve the lvalue identity of the argument. For example:
1) Built-in unary '&' applied to the parameter has to return the address 
of the actual argument
   void foo(const int& a, const int& b) {
     assert(&a == &b);
   }
   // The above 'assert' has to hold if called as
   int i;
   foo(i, i);
2) A non-constant argument can be legally modified through const 
reference by using 'const_cast'
   void foo(const int& a) {
     const_cast<int&>(a) = 42;
   }
   // The above modification is legal if called as
   int i;
   foo(i);
   assert(i == 42);
   // i.e. this assertion has to hold
3) Possible aliasing
   int x = 0;
   void foo(const int& a) {
     x = 42;
     assert(a == 42);
   }
   // The above 'assert' has to hold if called as
   foo(x);
Which means that the compiler can't simply treat const reference 
parameters as being equivalent to value parameters. They are not.
Of course, a very smart compiler can recognize these situations and 
stick to the strict semantics when they occur, while using const 
references and copied values interchangeably in all other cases. This is 
not simple though in general case.
Is any of these two forms preferable? Why?
In situations when you can use either, it might be more optimal to pass 
small objects by value and large objects by reference.
-- 
Best regards,
Andrey Tarasevich