9

I come across this output param convention, which favours pointers than references.

"Within function parameter lists all references must be const:

void Foo(const string &in, string *out);

In fact it is a very strong convention in Google code that input arguments are values or const references while output arguments are pointers. Input parameters may be const pointers, but we never allow non-const reference parameters except when required by convention, e.g., swap()."

That seems somewhat different to the accepted answer to this question, which says references should be used instead, unless the function involves some pointer arithmetic.

So I wonder if this input param is const reference, output param is pointer is just a matter of google-style, or it is a more generally accepted practice (to avoid non-const reference parameters).

Community
  • 1
  • 1
artm
  • 17,291
  • 6
  • 38
  • 54
  • 4
    You might consider the possibility, that the mentioned coding standard is not, let say it that way, the best in the world... – PiotrNycz Jul 26 '15 at 01:30
  • It's a generally accepted practice, as is using references for output parameters. Using references seems to be more popular, which I think is largely due to the fact that the C++ standard library does it (i.e. `swap()`). But just because something is less popular doesn't mean that everyone but Google shuns it. There are people outside of Google that follow this same convention. And there are people who don't follow the practice but think it's perfectly acceptable. I don't recall having met anyone who was strongly opposed to it. Ultimately this is a style of opinion more than of dogma. – Cornstalks Jul 26 '15 at 01:32
  • 1
    If you aren't being forced to used this guide at work then I wouldn't advise using it. Read [this](https://www.linkedin.com/pulse/20140503193653-3046051-why-google-style-guide-for-c-is-a-deal-breaker) – David G Jul 26 '15 at 01:47
  • It seems the standard has now been updated. The most recent standard says "Non-optional input parameters should usually be values or const references, while non-optional output and input/output parameters should usually be references (which cannot be null)." https://google.github.io/styleguide/cppguide.html#Inputs_and_Outputs – c.fogelklou May 20 '22 at 07:11
  • @DavidG 's link is broken, here it is the permanent link: https://web.archive.org/web/20210209211224/https://www.linkedin.com/pulse/20140503193653-3046051-why-google-style-guide-for-c-is-a-deal-breaker – alfC Jun 25 '22 at 00:31
  • @c.fogelklou, unfortunately `cpplint` 1.5.5 (Google's tool) still complains about this. I do this `cpplint --filter=-runtime/references`. – alfC Jun 25 '22 at 00:44

1 Answers1

9

You don't mention the rationale for this coding practice. The main reason I'm aware of is that it makes it clearer what's getting written when you scan your eyes over a block of code. Even if you don't remember exactly what every called function does, you can still tell when a variable is being modified, because you'll see its address being passed.

Also, changing a function to sometimes modify one of its parameters can't silently break other code. You have to go to every call site and call by pointer. Presumably you'll notice if one of the call sites needs you to not change that parameter there.

I can't speak to how widely adopted or loved this convention is, but that is the reasoning behind it, as far as I'm aware.

It can potentially lead to slightly less optimal compiler output. A call-by-reference means that callers can assume that only the actual variable was modified, and no pointer-arithmetic was done to modify other elements of the same array. (Unless you have cross-file compilation, the compiler can't know the pointer arg to the called function isn't treated as an array.)

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
  • 2
    Is that true? Certainly code can can take a parameter by const reference, then take its address, cast away const, and add onto it. That doesn't violate anything in the C++ specification, so an optimizer can't change the effect. – David Schwartz Jul 26 '15 at 02:22
  • @DavidSchwartz: "Unless you have cross-file compilation". So (deliberately or otherwise) he's talking about a function with internal linkage which can be completely optimised w.r.t. its calls [in the same TU]. Now, that's pretty dumb to bring up because this is a very rare situation. But it doesn't make his statement wrong. – Lightness Races in Orbit Jul 26 '15 at 02:26
  • 1
    @DavidSchwartz: I may be wrong about this, but I think the compiler is allowed to make assumptions about aliasing. i.e. that if you pass `&a[i]` to a function as a non-const pointer, the compiler will need to reload `a[i+1]` after the call, even if it had the value in a callee-saved register. This wouldn't be the case if you passed `a[i]` by non-const reference. I *may* be wrong about this, I haven't read up recently. – Peter Cordes Jul 26 '15 at 02:44
  • @LightnessRacesinOrbit: I'm talking about compiler options that effectively do whole-program optimization. (`gcc -fwhole-program`, or `gcc -flto` (Link-Time-Optimization)). Did this ever catch on for building software? I assume large programs don't use it, because it would be slower to compile. – Peter Cordes Jul 26 '15 at 02:50
  • I'm not sure. I recently wanted to use it but we're stuck on too old a GCC. I imagine that's fairly commonplace for "large programs". I don't think an increase in build times would generally matter _too_ much, though. – Lightness Races in Orbit Jul 26 '15 at 03:02
  • @LightnessRacesinOrbit: Arranging your build system to put *all* the source files on the command line of a single `gcc` invocation is more like the real reason, not build times. (Although I think the compile-time memory requirements could get really substantial, since the entire program's call tree would be exposed.) `-flto` certainly is less disruptive to build systems. – Peter Cordes Jul 26 '15 at 03:13
  • 1
    @PeterCordes: You don't need to do that. You just need to use `-flto` consistently across both compilation and link stages. – Lightness Races in Orbit Jul 26 '15 at 03:18