1

I came across this.

http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml?showone=Reference_Arguments#Reference_Arguments

According to the style guide, only const references are allowed as parameters. (That's what I understood)

Although, I don't seem to like that approach.

Comments?

user855
  • 19,048
  • 38
  • 98
  • 162
  • Duplicate: see http://stackoverflow.com/questions/1322517/passing-a-modifiable-parameter-to-c-function/1322547#1322547 – ChrisW Nov 23 '09 at 02:27

4 Answers4

8

Here are a couple of rules of thumb that can be useful when deciding between your options:

If you don't need to modify the object being passed into the function, consider whether the size of the object is less than or equal to the size of a pointer. If so, pass by value; otherwise, pass by const reference.

If you do need to modify the object being passed into the function, consider whether the parameter is optional (that is, null is a valid argument). If so, pass by pointer; otherwise, pass by non-const reference.

James McNellis
  • 348,265
  • 75
  • 913
  • 977
7

Google suggests only const references because they feel it is clearer to pass pointers when a function may modify the object. This is probably true, yet I prefer to only use pointers when null is a value that is acceptable.

To clarify, here is an example that explains the root of their argument.

Car c;
foo(c);

Whether c is modified by the function all depends on how it is declared and just looking at the call itself doesn't give much of an indication as to what could possibly happen.

void foo(Car c);  
void foo(const Car &c);  OR 
void foo(Car &c); 

Now consider

Car c;
foo(&c);

Having passed the address of your object, it is easier to see (from the callers perspective) whether or not the function may be changing your object. Granted, it is not a guarantee that it is as it could be a pointer to a const object, but from a code reviewers standpoint, it is easier to detect that this object may be changed as the function is passed a pointer. When Google's suggestion is strictly enforced, an object passed via a pointer would always be mutable, while anything not passed via a pointer would be const. (either by const & or b/c of pass by value)

Whether this is better or not is debatable. I would decide how you feel and be consistent across your team.

RC.
  • 27,409
  • 9
  • 73
  • 93
  • Good explanation but in the age of sophisticated IDEs passing pointers for the sake of readability seems like a dubious practice. – Duck Nov 23 '09 at 02:33
  • 2
    It's a Google practice. They have pretty strong ideas about many things... such as the use of incomplete constructors and `init` methods... I sometimes wonder if they program in C or C++ – Matthieu M. Nov 23 '09 at 07:53
  • "it is easier to detect that this object may be changed" Every time we see something passed by pointer, there is something in the mind saying "it could be changed!"? passing by &, const &, *, const *, are all the same in this regard. Passing a pointer doesn't change anything from the caller's perspective except by convention. – lmat - Reinstate Monica Jul 24 '18 at 12:50
2

it also enables that you can do

void x(const std::string& x)

x("hello");

without the const it wouldn't work.

Keith Nicholas
  • 43,549
  • 15
  • 93
  • 156
  • 1
    Why not? I don't see what you are getting at, can you expand on this? – Newton Falls Nov 23 '09 at 02:16
  • 1
    @Newton Falls: I think he means to say that "temporaries being rvalues cannot be bound to non-constant references" – Prasoon Saurav Nov 23 '09 at 14:04
  • The reason it wouldn't work is that, if the reference in the function were not const (i.e. it were mutable), what would change if it were modified? In this example, an rvalue is passed in. A temporary object that will be discarded as soon as the function call is over. Modifying the reference implies persistence outside of the function body, which is impossible for an rvalue. Thus it's a compiler error to bind an rvalue to a non-const reference. – scatter Jul 13 '21 at 03:47
2

It's a preference, as I can say this is a preference:

void align_left();
// vs.
void alignLeft();

Since you want to pass arguments by non const references, then do so. I don't prefer passing pointers. The convention typically has other implications (i.e. many programmers see a pointer and think the parameter may not be required, and then have to go check the docs). So you, in convention, would typically make the parameter name indicate that it would mutate the argument.

t_result getDate(t_string& outString) const;

The name then indicates the mutation. It can be a little deceptive, if you pass by ref very rarely in your codebase, but it is ultimately 'fine' and has enough positive implications. Regarding style, a lot of it comes back to consistency. As programs really expand, (IMO) this can really help - just make sure the intent of your program is clear and the style is consistent (at least you care to read style docs before you write a huge codebase).

justin
  • 104,054
  • 14
  • 179
  • 226
  • 1
    "It's a preference" Excellent answer. Thanks for not pretending that passing a pointer is a clue toward mutability (except by convention/style). You stress that consistency of style is key which is right on. Regarding "The [parameter] name then indicates the mutation", of course, if you're already looking at the declaration, the `const` is pretty easy to see (or not see). – lmat - Reinstate Monica Jul 24 '18 at 13:03