Where should I prefer pass-by-reference or pass-by-value? - c++

In what circumstances should I prefer pass-by-reference? Pass-by-value?

There are four main cases where you should use pass-by-reference over pass-by-value:
If you are calling a function that needs to modify its arguments, use pass-by-reference or pass-by-pointer. Otherwise, you’ll get a copy of the argument.
If you're calling a function that needs to take a large object as a parameter, pass it by const reference to avoid making an unnecessary copy of that object and taking a large efficiency hit.
If you're writing a copy or move constructor which by definition must take a reference, use pass by reference.
If you're writing a function that wants to operate on a polymorphic class, use pass by reference or pass by pointer to avoid slicing.

There are several considerations, including:
Performance
Passing by value copies the data, so passing large data structures by value can inhibit performance. Passing by reference passes only a reference (basically the address) to the data. For large data structures, this can greatly improve performance. For smaller data structures (like an int), passing by reference can inhibit performance.
Modifications
Passing by value copies the data so if the target code modifies that copy, it will not affect the original. Passing by reference passes only the address of the data, so modifications made against that reference will be "visible" to the calling code.

Yes.
Pass by value for things like native types that are small enough that passing them directly is efficient. Otherwise use pass by (const) reference.
The hard part is writing a template that could apply to either (in which case, you usually want to use pass by reference -- the potential penalty for passing a large object by value is much worse than the potential penalty for passing by reference when passing by value would have been preferred).
Edit: this, of course, is assuming a situation where the required semantics would allow either one -- obviously if you're working with something like polymorphic objects, there's no real "preference" involved, because you must use a pointer or reference to get correct behavior.

As others already have replied to your question sufficiently well, I would like to add an important point:
If the class does not have public copy-constructor, then you don't have choice to pass by value; you have to pass by reference (or you can pass pointer).
The following program would not compile:
class A
{
public:
A(){}
private:
A(const A&) {}
};
//source of error : pass by value
void f(A ) {}
int main() {
A a;
f(a);
return 0;
}
Error:
prog.cpp: In function ‘int main()’:
prog.cpp:10: error: ‘A::A(const A&)’ is private
prog.cpp:18: error: within this context
prog.cpp:18: error: initializing argument 1 of ‘void f(A)’
See yourself at ideone : http://www.ideone.com/b2WLi
But once you make function f pass by reference, then it compiles fine : http://www.ideone.com/i6XXB

here's the simple rule:
pass by reference when the value is large.
the other answers are amazing. Just trying to make this simplest.

You have tagged your question with both C and C++.
Therefore, I suggest that you consider using pass by reference in C++ which supports this feature and that you do not consider using it in C which does not support this feature.

pass by reference can be called only in below conditions:
Pass-by-references is more efficient than pass-by-value, because it does not copy the arguments. The formal parameter is an alias for the argument. When the called function read or write the formal parameter, it is actually read or write the argument itself.
The difference between pass-by-reference and pass-by-value is that modifications made to arguments passed in by reference in the called function have effect in the calling function, whereas modifications made to arguments passed in by value in the called function can not affect the calling function.
Use pass-by-reference if you want to modify the argument value in the calling function. Otherwise, use pass-by-value to pass arguments.
The difference between pass-by-reference and pass-by-pointer is
that pointers can be NULL or reassigned whereas references cannot.
Use pass-by-pointer if NULL is a valid parameter value or if you want to reassign the pointer.
Otherwise, use constant or non-constant references to pass arguments.

While pointers are references, "reference" in c++ usually refers to the practice of tagging a parameter of SomeType&.
Which you should never do. The only place it is appropriate is as a magic syntax required to implement the various pre-defined operators. Otherwise:
You should never pass out parameters by reference - pass by pointer, otherwise you make code reviews all but impossible. Pass by reference makes it impossible to tell by examining a call which parameters can be expected to be changed.
You should never pass in parameter by reference either. Again, this means you are performing a meta optimization. You should always just pass-by-value, otherwise you are guilty of peeking inside an object, examining its implementation and deciding that pass-by-reference is preferred for some reason.
Any c++ class should implement all the copy and assignment constructors and overloads necessary to be passed around by value. Otherwise it has not done its job, of abstracting the programmer from the implementation details of the class.

Related

How to set pointer to something if it's null and I can't deference it? [duplicate]

In what circumstances should I prefer pass-by-reference? Pass-by-value?
There are four main cases where you should use pass-by-reference over pass-by-value:
If you are calling a function that needs to modify its arguments, use pass-by-reference or pass-by-pointer. Otherwise, you’ll get a copy of the argument.
If you're calling a function that needs to take a large object as a parameter, pass it by const reference to avoid making an unnecessary copy of that object and taking a large efficiency hit.
If you're writing a copy or move constructor which by definition must take a reference, use pass by reference.
If you're writing a function that wants to operate on a polymorphic class, use pass by reference or pass by pointer to avoid slicing.
There are several considerations, including:
Performance
Passing by value copies the data, so passing large data structures by value can inhibit performance. Passing by reference passes only a reference (basically the address) to the data. For large data structures, this can greatly improve performance. For smaller data structures (like an int), passing by reference can inhibit performance.
Modifications
Passing by value copies the data so if the target code modifies that copy, it will not affect the original. Passing by reference passes only the address of the data, so modifications made against that reference will be "visible" to the calling code.
Yes.
Pass by value for things like native types that are small enough that passing them directly is efficient. Otherwise use pass by (const) reference.
The hard part is writing a template that could apply to either (in which case, you usually want to use pass by reference -- the potential penalty for passing a large object by value is much worse than the potential penalty for passing by reference when passing by value would have been preferred).
Edit: this, of course, is assuming a situation where the required semantics would allow either one -- obviously if you're working with something like polymorphic objects, there's no real "preference" involved, because you must use a pointer or reference to get correct behavior.
As others already have replied to your question sufficiently well, I would like to add an important point:
If the class does not have public copy-constructor, then you don't have choice to pass by value; you have to pass by reference (or you can pass pointer).
The following program would not compile:
class A
{
public:
A(){}
private:
A(const A&) {}
};
//source of error : pass by value
void f(A ) {}
int main() {
A a;
f(a);
return 0;
}
Error:
prog.cpp: In function ‘int main()’:
prog.cpp:10: error: ‘A::A(const A&)’ is private
prog.cpp:18: error: within this context
prog.cpp:18: error: initializing argument 1 of ‘void f(A)’
See yourself at ideone : http://www.ideone.com/b2WLi
But once you make function f pass by reference, then it compiles fine : http://www.ideone.com/i6XXB
here's the simple rule:
pass by reference when the value is large.
the other answers are amazing. Just trying to make this simplest.
You have tagged your question with both C and C++.
Therefore, I suggest that you consider using pass by reference in C++ which supports this feature and that you do not consider using it in C which does not support this feature.
pass by reference can be called only in below conditions:
Pass-by-references is more efficient than pass-by-value, because it does not copy the arguments. The formal parameter is an alias for the argument. When the called function read or write the formal parameter, it is actually read or write the argument itself.
The difference between pass-by-reference and pass-by-value is that modifications made to arguments passed in by reference in the called function have effect in the calling function, whereas modifications made to arguments passed in by value in the called function can not affect the calling function.
Use pass-by-reference if you want to modify the argument value in the calling function. Otherwise, use pass-by-value to pass arguments.
The difference between pass-by-reference and pass-by-pointer is
that pointers can be NULL or reassigned whereas references cannot.
Use pass-by-pointer if NULL is a valid parameter value or if you want to reassign the pointer.
Otherwise, use constant or non-constant references to pass arguments.
While pointers are references, "reference" in c++ usually refers to the practice of tagging a parameter of SomeType&.
Which you should never do. The only place it is appropriate is as a magic syntax required to implement the various pre-defined operators. Otherwise:
You should never pass out parameters by reference - pass by pointer, otherwise you make code reviews all but impossible. Pass by reference makes it impossible to tell by examining a call which parameters can be expected to be changed.
You should never pass in parameter by reference either. Again, this means you are performing a meta optimization. You should always just pass-by-value, otherwise you are guilty of peeking inside an object, examining its implementation and deciding that pass-by-reference is preferred for some reason.
Any c++ class should implement all the copy and assignment constructors and overloads necessary to be passed around by value. Otherwise it has not done its job, of abstracting the programmer from the implementation details of the class.

Pointer vs Reference difference when passing Eigen objects as arguments

If a have a function that takes a Eigen matrix as an argument, what would be the difference between:
void foo(Eigen::MatrixXd& container){
for(i=0;i<container.rows();i++){
for(j=0;j<container.cols();j++){
container(i,j)=47;
}
}
}
and
void foo(Eigen::MatrixXd* container){
for(i=0;i<container->rows();i++){
for(j=0;j<container->cols();j++){
container->coeffRef(i,j)=47;
}
}
}
In Eigen documentation, they only present the first method - does that mean that there are any advantages to that approach? And what are the drawbacks of not using const when passing the Matrix reference in the first case?
References are nice because there is no such thing as a null reference, so using a reference parameter reduces the risk of someone calling your function with an invalid value.
On the other hand some coding standards recommend making parameters you intend to modify pointers instead of non-const references. This forces the caller to explicitly take the address of any value they pass in making it more obvious the value will be modified. The choice of pointer vs. non-const reference is up to you.
However, if you do not intend to modify the parameter then making it a const reference is definitely the way to go. It avoids the problem of passing invalid pointers, allows you to pass in temporaries, and the caller doesn't care if the parameter is taken by reference since it isn't going to be modified.
With C++ code, there is the expectation that if a parameter is passed as pointer rather than reference, then the null pointer is a valid argument.
That is, by default you should use reference parameters. Only use pointers if the parameter is in some way "optional" and you want the caller to be able to pass the null pointer to signify "no value".
see the line:
container(i,j)=47.
That's not a constant operation, so you're not going to be able to set it to const.
One way a reference is different than a pointer is that your container reference can't be null. Pass by reference is a good way to avoid some errors while getting the benefits of not copying.

call by value vs const call by reference

I am a little confused about the differences between call by value and const call by reference. Could someone please explain this to me. For example, do they both protect against changing the callers argument, are they fast for all object sizes, do either copy the argument while one doesnt, and which use more memory when making a copy?
do they both protect against changing the callers argument
Passing by value creates a copy of the argument provided by the caller, so whatever the function does, it does it on a separate objects. This means the original object won't ever be touched, so in this case the answer is "Yes".
Passing by reference to const, on the other hand, lets the function refer the very same object that the caller provided, but it won't let that function modify it... Unless (as correctly remarked by Luchian Grigore in the comments) the function's implementer uses const_cast<> to cast away the const-ness from the reference, which is something that can be safely done only if it is known that the object bound to the reference was not declared to be of a const type (otherwise, you would get Undefined Behavior).
Since this does not seem to be the most likely scenario considering your question, and considering that in general accepting a reference to const represents a promise that the argument won't be touched, then the answer is that as long as we assume this promise to be fulfilled, passing by reference to const won't alter the argument provided by the caller. So the answer is "Yes" again - with the little caveat I mentioned above.
are they fast for all object sizes
No. Although you should first define "fast". If the type of the object being passed is expensive to copy (or to move, if a move is performed rather than a copy), then passing by value might be slow. Passing by reference will always cost you the same (the size of an address), no matter what is the type of the value you are passing.
Notice, that on some architecture and for some data types (like char) passing by value could be faster than passing by reference, while the opposite is generally true for large enough UDTs.
and which use more memory when making a copy?
Since only one of them is causing a copy, the question has an obvious answer.
The main difference is that passing by const reference (or non-const) doesn't make a copy of the argument. (the copy is actually subject to copy elision, but theoretically it's a copy that's passed to the function when you pass by value)
In some cases, passing by value is just as fast, or even faster (typically when the object is at most the size of a register). You'd usually pass basic types by value, and class-types by reference.
When passing by const reference you can still modify the original value just by casting the const away (via const_cast), but that results in undefined behavior if the original value is const.
call by value will copy all the elements of the object it does protect the callers argument because if you are going to change something it is only a copy you are changing.
calling by const reference does not copy elements but because of the "const" it will protect caller's argument.
You const reference.
I suppose that you mean the difference between:
void Fn1(MyType x);
and
void Fn2(const MyType& x);
In former case, a copy of the object is always created, which makes it slower especially if the type has a non-trivial constructor. The original object will be unaffected by any changes done on the copy within the function, but the copy itself can be changed.
The latter example will not create a copy and will in general be faster. Inside the function, only the const functions can be called on the argument (unless you resort to dirty tricks like casting away constness), thus guaranteeing that the object will not be modified.
IMPORTANT: This discussion doesn't cover types with special semantics, like smart pointers. In that case, call by value will still allow you to change what is logically the same object, i.e. not the smart ptr instance itself but the object it points to.
So here are the answers to your questions:
do they both protect against changing the callers argument: yes, the original object will remain unchanged (excluding tricks)
are they fast for all object sizes: they are not equally fast - call by reference is in general faster, except for some primitive types where speed is more or less the same or maybe even marginally faster, depending on compiler optimizations.
do either copy the argument while one doesnt: call by value creates a copy, call by reference doesn't
which use more memory when making a copy? call by reference doesn't create a copy so the answer is clear
One other point worth mentioning is that call-by-reference functions are converted into inline functions.

When should I use a reference?

Newbie here, I am reading some code, and I see sometimes the author used the reference in a function as
funca (scalar& a)
// Etc
Sometimes he just use
funcb (scalar a)
// Etc
What's the difference? Is using a reference a good habit that I should have?
Thank you!
If you call foo(scalar a), the argument a of type scalar will be COPIED from the caller and foo will have it's own COPY of the original object.
If you call foo(scalar &b), the argument b will be just a reference to the original object, so you will be able to modify it.
It's faster to pass an object by reference using the &name syntax, since it avoids creating a copy of the given object, but it can be potentially dangerous and sometimes the behavior is unwanted because you simply want an actual copy.
That being said, there's actually an option that disallows the ability to modify the original object for the called function yet avoids creating a copy. It's foo(const scalar &x) which explicitly states that the caller does not want the function foo to modify the object passed as an argument.
Optional reading, carefully:
There's also a way of passing an argument as a raw pointer which is very rare in modern C++. Use with caution: foo(scalar *a). The caller has got to provide the address of an object instead of the object itself in this scenario, so the caller would call foo(&a). For the called function foo to be able to modify the object itself in this case, it would need to dereference the pointer a, like this in foo: *a =. The star in front of the variable name in this case says that we don't want to modify the address that we have received (as a direct result of the calling function providing &a, that is, the address of the object a).
Passing a parameter by reference allows the called function to modify its argument in a way that will be visible to the caller after the function returns, while passing by value means that any changes will be limited in scope to the called function. Therefore passing by (non-const) reference typically signifies that the callee intends to modify the argument or, less commonly, use it as an additional "return value".
Additionally, passing by reference means that no copy of the parameter needs to be made; passing by value requires such a copy (which may be detrimental for the memory footprint or runtime performance of your application). For this reason you will often see arguments of class type being passed as a const reference: the callee does not intend to modify the argument but it also wants to avoid a copy being made. Scalar arguments are of very small size, so they do not benefit from this approach.
See also Pass by Reference / Value in C++.
Call by value (funcb (scalar a)) will give the function a copy of the argument, so changes made to the argument are not visible to the caller.
Call by reference (funcb(scalar& b)) means that the function operates directly on the argument, so any changes made are directly visible to the caller.
Whether or not call by reference is a good practice depends on the circumstances. If you need the function to modify the argument (and the modifications to be visible to the caller) you obviously want to use call by reference. If you don't want to modify the argument using non-const reference arguments is misleading (since the signature indicates the argument could be changed), so call by value is more apropriate here. Of course for more complex types call by value can have a non-trivial overhead. In these cases call-by-const-reference is preferable (funcc(const scalar& c))

when to pass function arguments by reference and when by address?

Could anyone explain with some examples when it is better to call functions by reference and when it is better to call by address?
This has already been discussed. See Pointer vs. Reference.
Pass your arguments to function using reference whenever possible.
Passing arguments by reference eliminate the chance of them being NULL.
If you want it to be possible to pass NULL value to a function then use pointer.
One nice convention is to:
Pass objects by pointer whenever they may be manipulated (side-effect or as output) by the function.
Pass all other objects by const reference.
This makes it very clear to the caller, with minimal documentation and zero performance cost, which parameters are const or not.
You can apply this to primitive types as well, but it's debatable as to whether or not you need to use const references for non-output parameters, since they are clearly pass-by-value and cannot act as output of the function in any way (for direct types - not pointers/references - of course).