Related
This question already has answers here:
C++: Is it better to pass an enum as a value or as a const reference?
(5 answers)
Closed 7 years ago.
Correct my if I'm wrong, but the reason you pass integers and other basic data types by value is because the memory they occupy is too small, so it's a waste to make a pointer variable of that data type (which will probably be at least the same size as the data type).
That's why I always pass ints and other basic types by value to functions, and other (bigger) data types are passed by const references or by pointers of const. Did I grasp this right?
Now I've seen many APIs that pass enum types as const references, like so:
enum FileOptions { ReadOnly, ReadWrite, WriteOnly };
void processFile(const FileOptions &options);
As far as I know, enums are usually interpreted by the compiler as plain integers, so why are they passed by references? Is it done to abstract the data type from the developer, so he won't think of FileOptions as an integer? (although it is).
The only advantage I can see is, that if you later decide to create a class with extended funcitonality, you can pass it still efficiently without changing the code everwhere.
Any decent optimizer doesn't care for the reference if it is a const reference for a base type anyway, and creates the same code in both cases.
Another consequence could be if the reference is to some other variable and it is changed by another thread, it can even change it's value during the course of your function (even though it says it's const) which, I would think, is not really desireably. In this case it would heavily depend on the optimization what value is used in a given branch of that method.
You are right, the enum is basically a 'const int'.
Second guessing why some developer chose a certain style is futile.
Unless you call the function in a very close loop it doesn't matter anyhow.
In modern C++ there is also enum class which is strongly typed enums.
I think const reference is used only for similarity and easy to modificate in future.
For example you have a class with a lot of methods, all parameters in this methods usually complex objects and of course passed by const reference. So you declare the enum parameter in the same way. And you will know for sure that it's should not be changed and so on
Later you may deside to convert enum in more complex object, and you will no need to update function declaration at all. It's already suitable for such refactoring
There is one big difference: If you pass options as a value, then it becomes a local variable in your function, and only your function can change it. If you pass options as a const&, then there is a variable somewhere, which might be a static or global variable, and if your function modifies any other variable of type FileOptions, then it might be the one that was passed to you as a const&, so the value of options might change.
And if your function calls another function, then that function might change the variable behind options. So as a developer, after any function call you could suspect that options might have changed (although if that happens, that would be about the worst possible programming style imaginable), but also the compiler would have to assume that it has changed unless it can prove otherwise.
Modifying a const& in that way would be awful, so we can safely assume that unless the caller absolutely hates you a const& won't be changed. You use const& when you actually want to pass a value, but passing it by reference seems to be more efficient. For an int that is pointless, for an array containing ten megabytes worth of int's it's not at all pointless.
Another use for const& instead of value is for objects that cannot easily be copied. For example a mutex cannot easily be copied. Or an object giving exclusive access to a file can by definition not be copied in a meaningful way.
With C++ how do i decide if i should pass an argument by value or by reference/pointer? (tell me the answer for both 32 and 64bits) Lets take A. Is 2 32bit values more less or equal work as a pointer to a 32bit value?
B to me seems like i always should pass by value. C i think i should pass by value but someone told me (however i haven't seen proof) that processors don't handle values not their bitsize and so it is more work. So if i were passing them around would it be more work to pass by value thus byref is faster? Finally i threw in an enum. I think enums should always be by value
Note: When i say by ref i mean a const reference or pointer (can't forget the const...)
struct A { int a, b; }
struct B { int a; }
struct C { char a, b; }
enum D { a,b,c }
void fn(T a);
Now tell me the answer if i were pushing the parameters many times and the code doesn't use a tail call? (lets say the values isnt used until 4 or so calls deep)
Forget the stack size. You should pass by reference if you want to change it, otherwise you should pass by value.
Preventing the sort of bugs introduced by allowing functions to change your data unexpectedly is far more important than a few bytes of wasted stack space.
If stack space becomes a problem, stop using so many levels (such as replacing a recursive solution with an iterative one) or expand your stack. Four levels of recursion isn't usually that onerous, unless your structures are massive or you're operating in the embedded world.
If performance becomes a problem, find a faster algorithm :-) If that's not possible, then you can look at passing by reference, but you need to understand that it's breaking the contract between caller and callee. If you can live with that, that's okay. I generally can't :-)
The intent of the value/reference dichotomy is to control what happens to the thing you pass as a parameter at the language level, not to fiddle with the way an implementation of the language works.
I pass all parameters by reference for consistency, including builtins (of course, const is used where possible).
I did test this in performance critical domains -- worst case loss compared to builtins was marginal. Reference can be quite a bit faster, for non-builtins, and when the calls are deep (as a generalization). This was important for me as I was doing quite a bit of deep TMP, where function bodies were tiny.
You might consider breaking that convention if you're counting instructions, the hardware is register-starved (e.g. embedded), or if the function is not a good candidate for inlining.
Unfortunately, the question you ask is more complex than it appears -- the answer may vary greatly by your platform, ABI, calling conventions, register counts, etc.
A lot depends on your requirement but best practice is to pass by reference as it reduces the memory foot print.
If you pass large objects by value, a copy of it is made in memory andthe copy constructor is called for making a copy of this.
So it will take more machine cycles and also, if you pass by value, changes are not reflected in the original object.
So try passing them by reference.
Hope this has been helpful to you.
Regards, Ken
First, reference and pointers aren't the same.
Pass by pointer
Pass parameters by pointers if any/some of these apply:
The passed element could be null.
The resource is allocated inside the called function and the caller is responsible should be responsible for freeing such a resource. Remember in this case to provide a free() function for that resource.
The value is of a variable type, like for example void*. When it's type is determined at runtime or depending on the usage pattern (or hiding implementation - i.e Win32 HANDLE), such as a thread procedure argument. (Here favor c++ templates and std::function, and use pointers for this purpose only if your environment does not permit otherwise.
Pass by reference
Pass parameters by reference if any/some of these apply:
Most of the time. (prefer passing by const reference)
If you want the modifications to the passed arguments to be visible to the caller. (unless const reference is used).
If the passed argument is never null.
If you know what is the passed argument type and you have control over function's signature.
Pass by copy
Pass a copy if any/some of these apply:
Generally try to avoid this.
If you want to operate on a copy of the passed argument. i.e you know that the called function would create a copy anyway.
With primitive types smaller than the system's pointer size - as it makes no performance/memory difference compared to a const ref.
This is tricky - when you know that the type implements a move constructor (such as std::string in C++11). It then looks as if you're passing by copy.
Any of these three lists can go more longer, but these are - I would say - the basic rules of thumb.
Your complete question is a bit unclear to me, but I can answer when you would use passing by value or by reference.
When passing by value, you have a complete copy of the parameter into the call stack. It's like you're making a local variable in the function call initialized with whatever you passed into it.
When passing by reference, you... well, pass by reference. The main difference is that you can modify the external object.
There is the benefit of reducing memory load for large objects passing by reference. For basic data types (32-bit or 64-bit integers, for example), the performance is negligible.
Generally, if you're going to work in C/C++ you should learn to use pointers. Passing objects as parameters will almost always be passed via a pointer (vs reference). The few instances you absolutely must use references is in the copy constructor. You'll want to use it in the operators as well, but it's not required.
Copying objects by value is usually a bad idea - more CPU to do the constructor function; more memory for the actual object. Use const to prevent the function modifying the object. The function signature should tell the caller what might happen to the referenced object.
Things like int, char, pointers are usually passed by value.
As to the structures you outlined, passing by value will not really matter. You need to do profiling to find out, but on the grand scheme of a program you be better off looking elsewhere for increasing performance in terms of CPU and/or memory.
I would consider whether you want value or reference semantics before you go worrying about optimizations. Generally you would pass by reference if you want the method you are calling to be able to modify the parameter. You can pass a pointer in this case, like you would in C, but idiomatic C++ tends to use references.
There is no rule that says that small types or enums should always be passed by value. There is plenty of code that passes int& parameters, because they rely on the semantics of passing by reference. Also, you should keep in mind that for any relatively small data type, you won't notice a difference in speed between passing by reference and by value.
That said, if you have a very large structure, you probably don't want to make lots of copies of it. This is where const references are handy. Do keep in mind though that const in C++ is not strictly enforced (even if it's considered bad practice, you can always const_cast it away). There is no reason to pass a const int& over an int, although there is a reason to pass a const ClassWithManyMembers& over a ClassWithManyMembers.
All of the structs that you listed I would say are fine to pass by value if you are intending them to be treated as values. Consider that if you call a function that takes one parameter of type struct Rectangle{int x, y, w, h}, this is the same as passing those 4 parameters independently, which is really not a big deal. Generally you should be more worried about the work that the copy constructor has to do - for example, passing a vector by value is probably not such a good idea, because it will have to dynamically allocate memory and iterate through a list whose size you don't know, and invoke many more copy constructors.
While you should keep all this in mind, a good general rule is: if you want refence semantics, pass by refence. Otherwise, pass intrinsics by value, and other things by const reference.
Also, C++11 introduced r-value references which complicate things even further. But that's a different topic.
These are the rules that I use:
for native types:
by value when they are input arguments
by non-const reference when they are mandatory output arguments
for structs or classes:
by const reference when they are input arguments
by non-const reference when they are output arguments
for arrays:
by const pointer when they are input arguments (const applies to the data, not the pointer here, i.e. const TYPE *)
by pointer when they are output arguments (const applies to the data, not the pointer)
I've found that there are very few times that require making an exception to the above rules. The one exception that comes to mind is for a struct or class argument that is optional, in which case a reference would not work. In that case I use a const pointer (input) or a non-const pointer (output), so that you can also pass 0.
If you want a copy, then pass by value. If you want to change it and you want those changes to be seen outside the function, then pass by reference. If you want speed and don't want to change it, pass by const reference.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 11 years ago.
I work with C++ in an embedded environment (actually a subset of C++) and want some advice on the use of pointers/references when passing arguments to routines.
A common tip goes something like "use references when you can, and pointers when you have to". I believe this is related to avoiding null pointers.
However, our current programming guideline prohibits the use of references.
Please refer to the discussion thread below, and see if you agree.
Bert:
We should be taking advantage of passing arguments by reference (built-in null pointer protection) when appropriate. This would yield smaller, more robust code.
Ernie:
I disagree. Using references hides what parameters might be changed and as such, when you are reviewing code or looking at what a particular function is doing, you now have to look at each and every function it calls, and each and every function they call to see if any of the parameters you are passing in might get changed.
Whereas, if you use pointers, then you know by the fact that if you are passing in a pointer, it might get changed. If you are not passing in a pointer, then you know it has not been changed.
This ease in maintenance is worth the NULL pointer issues. With references, just because you don't have NULL pointer issues, does not mean that the object has been correctly initialized and that you have good data.
Bert:
That concern can be mitigated by labeling input parameters (references) as "const". (This is similar to the Google coding style.) Then you know the other parameters are the ones that may be modified. The modifiable parameters can start with the "r" prefix, which was allowed in our guidelines earlier. (And don't be surprised when tools such as Visual Assist color code inputs/outputs to help give visual cues.)
Ernie:
Labeling parameter (references) as "const" does NOT mitigate the problem. Because when you are up a level and someone is calling the function, then you have just a regular variable like "nSomeNumber". You MUST go to the function prototype to see if that variable might get changed. Or, you MUST hover over the function to see the prototype. So you can not just quickly scan code and have an idea of what might be happening.
Also, there are times where you do not have color coding, like in Beyond Compare during a code review, and you can not easily hover or go to the prototype.
I am strongly against the use of references, as they make code maintenance and readability difficult and error prone; and the errors you get are not the simple to detect NULL pointer issues, they are logic errors where a value is set above a function and passed into the function as a reference, and then after the function is called the value is used and not having expected it to change.
Grover:
FYI, Google allows const reference for arguments. Presumably, this is to save on the cost of copying objects. Google does not allow simple reference for arguments. If an object is to change, then pass it by pointer.
http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Reference_Arguments
A common tip goes something like "use references when you can, and pointers when you have to". I believe this is related to avoiding null pointers.
This is good advice, and yes, avoiding null pointers is the reason (it's also easier to read as you don't have to constantly dereference references, or use ->)
Grover: FYI, Google allows const reference for arguments. Presumably, this is to save on the cost of copying objects. Google does not allow simple reference for arguments. If an object is to change, then pass it by pointer.
I can understand the argument against using non-const references. In that case, Google's style guide is the best approach (use const references for inputs, pointers for outputs). Not using const references for inputs is just madness: you either have to pass by value, which will be incredibly slow, or pass by pointer, which is going to require a hell of a lot of address taking and dereferencing (not to mention pointless null pointer checks). That would make the code far more unreadable than worrying about modified references.
What I'd suggest is that references be always const (like in Google style) unless it is obvious from the function's task that an argument might end up modified inside the function. This should, IMO, happen only when all other ways are much less readable, i.e. you should generally try to keep functions as 'functional' as possible, taking const arguments and returning something else. Depending on how big this subset of C++ is, that should not be a problem: mutable state information you might be tempted to change in a function f can almost always be organized in a way so that this information resides in a class c which f is a member of, and then you can further seperate apart 'modifying functions' and 'pure functions', so that your functions are in the end mostly of either of the forms
class c;
ret_T f0(const arg1T &, const arg2T &, ...);
ret_T c::f1(const arg1T &, const arg2T &, ...) const; // pure functions
void c::f3(const arg1T &, const arg2T &, ...); // modifying functions
c &c::f2(const arg1T &, const arg2T &, ...){
... return *this;
}
Obviously, that's not always possible or at least not always feasible, but it is often enough so that it won't hurt to give those functions that don't fit in this schema (i.e. functions that return something nontrivial and modify the state) nice long descriptive names to make it clear that they will.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
I have joined a new group that has coding guidelines that (to me) seem dated.
But just rallying against the machine without valid backup is not going to get me anywhere.
So I am turning to SO to see if we can up with rational reasons for/against (hey I may be wrong in my option so both sides of the argument would be appreciated).
The guideline that is up for argument is:
Tip: Use pointers instead of references for return arguments.
void Func1( CFoo &Return ); // bad
void Func2( CFoo *pReturn ); // good
Justification:
When you use a reference, it looks the same as a value. The caller may be surprised that his value has been changed after calling the function. The callee may innocently modify the value without meaning to affect the caller's value. By using a pointer, it is clear to both the caller and callee that the value can be changed. Using references can be particularly misleading in code reviews.
When you use a reference, it looks the same as a value.
Only if you really aren't paying attention to what you are doing. Ok, sometimes that happens, but really... no amount of coding standards can correct for people not paying attention or not knowing what they are doing.
The caller may be surprised that his value has been changed after calling the function.
If you are surprised by what happens when you call a function, then the function is poorly documented.
Given a function's name, its parameter list, and perhaps some very brief and descriptive documentation, it should be eminently clear what the function does and what its observable side effects are (including whether any arguments are modified).
The callee may innocently modify the value without meaning to affect the caller's value.
If the function is const correct, then this isn't a problem. If the function isn't const correct, then it should be made const correct, if you can (retroactively making code const correct can be an absolute beating).
This rationale doesn't make much sense, though: when you are actually writing the code for a function, you should be able to see the declarations of the parameters. If the function is so long that you can't, it's time for refactoring.
By using a pointer, it is clear to both the caller and callee that the value can be changed.
This is not entirely correct. A function can take a pointer to const object, in which case the object cannot be changed.
Using references can be particularly misleading in code reviews.
Only if the people doing the code reviews don't know what they are doing.
All of that is well and good, but why should pass-by-reference be used instead of pass-by-pointer? The most obvious reason is that a reference cannot be null.
In a function that takes a pointer, you have to check that the pointer is not null before you use it, at least with a debug assertion. During a proper code review you have to analyze more code to be sure that you don't accidentally pass a null pointer to a function that doesn't expect one. I've found that it takes much longer to review functions that take pointer arguments for this very reason; it's so much easier to get it wrong when using pointers.
It seems to me that the proper use of const would (mostly) eliminate the need for that tip. The part that still seems useful is when reading caller code, seeing:
Func1(x);
it isn't quite clear what is being done with x (particularly with a nondescript name like Func1). Instead using:
Func2(&x);
with the above convention, indicates to the caller that they should expect x to be modified.
If you have not already, buy a copy of Herb Sutter and Andrei Alexandrescu's "C++ Coding Standards: 101 Rules, Guidelines and Best Practices." Read it. Recommend it to your co-workers. It's a good base for a local coding style.
In Rule 25, the authors recommend:
"Prefer passing by reference if the argument is required and the function won't store a pointer to it or otherwise affect its ownership. This states that the argument is required and makes the caller responsible for providing a valid object."
"Argument is required" means NULL is not a valid value.
One of the most frequent causes of defects is accidental de-referencing of null pointers. Using references instead of pointers in these cases can eliminate these at compile-time.
So you have a trade-off -- eliminate a frequent source of errors, or ensure understandability of calling code by means other than the function name. I personally lean toward eliminating risk.
While I wouldn't use the tip's advice myself, the justification is valid, which is why languages like C# introduced the out and ref keywords for use at the call site.
The best argument I can come up for against it is this: instead of requiring people to use pointers, you should instead require that people write function names that reflect what the function does. When I call std::swap, I know it's going to change the value of the arguments because the name implies that. On the other hand, if I were to call a function getSize, I wouldn't expect that to modify any arguments.
Coding standards are based on habits as much as common sense. Some of your coworkers may rely on years of ingrained assumptions that a parameter not passed by pointer won't change - have pity on them.
The important part of coding standards is not that they're optimal, but that they're adhered to by everybody so that there's some consistency to the body of code.
If they really want explicit mention of out parameters at the call site, they should actually require that instead of hacking around it by trying to make pointers mean something they don't. Pointers don't imply modification any more than references do, and it's not uncommon to pass pointers for non-modified objects.
One potential way to express out parameters explicitly:
template<class T>
struct Out {
explicit Out(T& obj) : base(obj) {}
T& operator*() { return base; }
T* operator->() { return &base; }
private:
T& base;
};
template<class T>
Out<T> out(T& obj) {
return Out<T>(obj);
}
void f(Out<int> n) {
++*n;
}
int main() {
int n = 3;
f(out(n));
cout << n << '\n';
}
And as a temporary measure until they change old code to this, you can make the Out convertible to a pointer and/or reference:
// in class definition
operator T*() { return &base; }
operator T&() { return base; }
// elsewhere
void old(int *p);
void g() {
int n;
old(out(n));
}
I went ahead and wrote the various classes required for this, and for in-out parameters, in a way that should degrade nicely. I doubt I'll be using that convention any time soon (in C++, at least), but it'll work for anyone that wants to make call sites explicit.
I found there are two schools of though about this:
(a) use a pointer to show a parameter may be modified
(b) use a pointer if and only if the parameter may be null.
I agree with your motivation for (a): when reading code, you can't know all declarations, even if a mouseover gives you the declaration of the function. Mousing over hundreds of functions in thousands of lines just takes time.
I certainly see a problem here if you mix in and out parameters:
bool GetNext(int index, Type & result);
A call to this fuinction would look like this:
int index = 3;
Type t;
if (!GetNext(index, t))
throw "Damn!";
In that example, the call itself is fairly obvious, to potentially modify t. But what about index? Maybe GetNext increments the index, so you always get the next item, without the callee needing to keep caller state?
Which usually raises the reply Then the method should be GetNextAndIncrementIndex, or you should use an iterator anyway. I bet these people never had to debug code written by electrical engineers that still think Numerical Recipes is the Holy Grail of programming.
Howver I still tend to (b): simply because the problem can be avoided for new code being written, and "may be null or not" is usually the more common problem.
The justification is logically true.
It may surprise coders that the value has changed (because they thought the value was being passed by value).
But does logically true provide any meaning in this context.
So the value may change. How does this affect the correctness of the code?
Apart from it may print out a different value then an illogical human expects, but the code is doing what it is supposed to be doing and the compiler is enforcing constraints.
i recommend:
pass by reference (do not pass by pointer)
pass by const reference wherever possible (assuming you've used const correctly throughout your codebase)
place arguments/parameters which mutate at the beginning of the list
label the function appropriately
label the argument appropriately (and create methods/functions with detailed and descriptive names and few arguments)
document the result
if multiple arguments/parameters mutate, consider creating a simple class which holds these arguments (even if by reference themselves)
if they still can't function (sic) without visual and documented cues, create a lightweight template container object for the parameter which mutates, which is then passed to the method or function
I would disagree with this guideline. The confusion mentioned in the justification can be easily resolved by making sure the code is const-correct. If you are passing an input parameter to a function by reference, then it should be a const reference. If the reference is not const, that is an indication that it is an output parameter, whose value may be changed by the function.
Furthermore, when you pass a pointer to a function, rather than a reference, that instantly raises a question about whether or not this is a pointer to dynamically allocated memory, and whether or not it should be freed. Using a reference removes the temptation to call delete.
There are times when passing a pointer is appropriate, such as when it actually is a pointer to a dynamically allocated object or array, or when it makes sense for it to be null. Although, you should prefer a smart pointer in such cases. In all other cases a reference is better, IMHO.
Provided, I want to pass a modifiable parameter to a function, what should I choose: to pass it by pointer or to pass it by reference?
bool GetFoo ( Foo& whereToPlaceResult );
bool GetFoo ( Foo* whereToPlaceResult );
I am asking this because I always considered it the best practice to pass parameter by reference (1), but after examining some local code database, I came to a conclusion, that the most common way is (2). Moreover, the man himself (Bjarne Stroustrup) recommends using (2). What are the [dis]advantages of (1) and (2), or is it just a matter of personal taste?
I prefer a reference instead of a pointer when:
It can't be null
It can't be changed (to point to something else)
It mustn't be deleted (by whoever receives the pointer)
Some people say though that the difference between a reference and a const reference is too subtle for many people, and is invisible in the code which calls the method (i.e., if you read the calling code which passes a parameter by reference, you can't see whether it's a const or a non-const reference), and that therefore you should make it a pointer (to make it explicit in the calling code that you're giving away the address of your variable, and that therefore the value of your variable may be altered by the callee).
I personally prefer a reference, for the following reason:
I think that a routine should know what subroutine it's calling
A subroutine shouldn't assume anything about what routine it's being called from.
[1.] implies that making the mutability visible to the caller doesn't matter much, because the caller should already (by other means) understand what the subroutine does (including the fact that it will modify the parameter).
[2.] implies that if it's a pointer then the subroutine should handle the possibility of the parameter's being a null pointer, which may be extra and IMO useless code.
Furthermore, whenever I see a pointer I think, "who's going to delete this, and when?", so whenever/wherever ownership/lifetime/deletion isn't an issue I prefer to use a reference.
For what it's worth I'm in the habit of writing const-correct code: so if I declare that a method has a non-const reference parameter, the fact that it's non-const is significant. If people weren't writing const-correct code then maybe it would be harder to tell whether a parameter will be modified in a subroutine, and the argument for another mechanism (e.g. a pointer instead of a reference) would be a bit stronger.
Advantages to passing by reference:
Forces user to supply a value.
Less error-prone: Handles pointer dereferencing itself. Don't have to check for null inside.
Makes the calling code look much cleaner.
Advantages to passing pointer by value:
Allows null to be passed for "optional" parameters. Kinda an ugly hack, but sometimes useful.
Forces caller to know what is being done w/ the parameter.
Gives the reader half a clue of what might be being done w/ the parameter without having to read the API.
Since reference passing is in the language, any non-pointer parameters might be getting modified too, and you don't know that pointer values are being changed. I've seen APIs where they are treated as constants. So pointer passing doesn't really give readers any info that they can count on. For some people that might be good enough, but for me it isn't.
Really, pointer passing is just an error-prone messy hack leftover from C which had no other way to pass values by reference. C++ has a way, so the hack is no longer needed.
One advantage to passing by reference is that they cannot be null (unlike pointers), obviating the need to null-check every out parameter.
I'd recommend that you consider (may not be best for every situation) returning Foo from the function rather than modifying a parameter. Your function prototype would look like this:
Foo GetFoo() // const (if a member function)
As you appear to be returning a success/failure flag, using an exception might be a better strategy.
Advantages:
You avoid all of the pointer/reference issues
Simplifies life for the caller. Can pass the return value to other functions without using a local variable, for example.
Caller cannot ignore error status if you throw an exception.
Return value optimization means that it may be as efficient as modifying a parameter.
I choose #2 because it obvious at the point of call that the parameter will be changed.
GetFoo(&var) rather than GetFoo(var)
I prefer pass by reference for just const references, where I am trying to avoid a copy constructor call.
Pass by reference, and avoid the whole NULL pointer problem.
I seem to recall that in c++ references where not null and pointers could be. Now I've not done c++ for a long time so my memory could be rusty.
The difference here is relatively minor.
A reference cannot be NULL.
A nullpointer may be passed.
Thus you can check if that happens and react accordingly.
I personally can't think of a real advantage of one of the two possibilities.
I find this a matter of personal taste. I actually prefer to pass by reference because pointers give more freedom but they also tend to cause a lot of problems.
The benefit to a pointer is that you can pass nothing, ie. use it as if the parameter was completely optional and not have a variable the caller passes in.
References otherwise are safer, if you have one its guaranteed to exist and be writeable (unless const of course)
I think its a matter of preference otherwise, but I don't like mixing the two as I think it makes maintainace and readability of your code harder to do (especially as your 2 functions look the same to the caller)
These days I use const references for input parameters and pointers for out parameters. FWIIW, Google C++ Style Guide recommends the same approach (not that I always agree with their style guide - for instance they don't use exceptions, which usually does not make much sense)
My preference is a reference. First, because it rhymes. :) Also because of the issues pointed out by other answers: no need to dereference, and no possibility of a reference being NULL. Another reason, which I have not seen mentioned, is that when you see a pointer you cannot be sure whether or not it points to dynamically allocated memory, and you may be tempted to call delete on it. A reference, on the other hand, dispenses with any ambiguity regarding memory management.
Having said that, there are of course many cases when passing a pointer is preferable, or even necessary. If you know in advance that the parameter is optional, then allowing it to be NULL is very useful. Similarly, you may know in advance that the parameter is always dynamically allocated and have the memory management all worked out.