15

In Other C++ Features, Reference Arguments of the Google C++ Style Guide, I read that non-const references must not be used.

All parameters passed by reference must be labeled const.

It is clear that looking at function calls that use references as arguments is absolutely confusing for C programmers, but C and C++ are different languages now. If an output parameter is required, using a pointer for a required output parameter, may cause the whole function body to be skipped, which makes the implementation of a function more complicated (formally increases the cyclomatic complexity and depth of a function).

I'd like to make C++ code as easy to understand/maintain as possible, so I'm generally interested to read coding style guides. But as to adapt best practices in a team, I think that understanding the rationale behind style guide elements is an important factor.

Are non-const references really that bad? Is banning them only Google specific or is it a commonly accepted rule? What justifies the extra effort for implementing output parameters as pointers?

6
  • 2
    "using a pointer for it causes the whole function body to be skipped" er, what? Oct 5, 2015 at 9:39
  • @ratchetfreak I tried to clarify this. I admit that functions like this may show some design flaws. A pointer is always formally optional so it has to be checked before dereferencing it.
    – Wolf
    Oct 5, 2015 at 9:46
  • 5
    Google's C++ style guide is pretty backwards. In my subjective opinion, it should be burned.
    – Siyuan Ren
    Oct 5, 2015 at 12:47
  • 1
    As for this particular item, I think the rationale is that forcing programmers to write an ampersand when the arguments may be mutated show clearer intent.
    – Siyuan Ren
    Oct 5, 2015 at 13:02
  • 5
    The Google Style Guide was written as it was, to support homogeneous code in Google legacy projects. If you are not working on legacy projects (that were written with this style guide from the beginning), you should probably not use it (it specifies lots of rules that are not good for new code (c++11, c++14, c++17)).
    – utnapistim
    Oct 6, 2015 at 9:11

3 Answers 3

19

The rationale behind Google's style guide is simply to make it clear from a function's call site whether a parameter is an input parameter or an output parameter. (See here for further discussion.) Other languages make out parameters explicit by design; C#, for example, has an out keyword that must be used at the call site. Since C++ doesn't make it explicit, Google chose to use const ref. versus pointer to make it clear.

Is this only a Google rule? No, but I doubt it's very widespread. I don't think I've seen it outside of Google's style guide and groups that explicitly adhere to parts of the Google style guide. (For example, I liked the idea when I first read the Google style guide years ago and have used it for some of my own code.)

In particular, the newly announced C++ Core Guidelines prefer return values to output parameters for (almost) everything and uses non-const refs for the rest. Google's use of pointers versus references might make output parameters clearer, but return values are clearer still. Now that C++11 has standardized moves (rvalue references, &&, to make returns of many types cheap) and tuples (allowing an easy way to return multiple values), many of the use cases for out parameters no longer apply.

The C++ Core Guidelines have some big names (Bjarne Stroustrup, Herb Sutter) behind them, are supported by Microsoft, and embrace the latest C++ features (unlike Google's style guide), so I expect its recommendations to be more popular than Google's.

3
  • Thanks for your answer (also for the brief excursion to C#). Easy reviewing is of course an important point, especially in Open Source projects. With cheap returns in modern C++, these considerations will lose their importance. With older legacy software and it's aged compilers it may be still helpful.
    – Wolf
    Oct 5, 2015 at 14:18
  • I didn't forget about it, but C++ Core Guidelines is not as quick to get. It's interesting that it's Philosophy shows the rationale behind the rules and also a modernized view on programming ("Express ideas directly in code" reads a little bit like the Zen of python) as a way to communicate.
    – Wolf
    Oct 5, 2015 at 14:37
  • Supplement: direct link to the Philosophy section of the C++ Code Guidelines.
    – Wolf
    Feb 19, 2020 at 8:30
1

There are 2 options for dealing with an invalid pointer passed in, first check and early return or let it be undefined behavior (if you care more about speed than robustness).

Checking is as simple as:

void foo(void* buffer){
    if(buffer == nullptr)
        return;

    //actually foo

    // note no increase in indentation required

}

This type of check is generally accepted as a parameter check. If you see the code it's quite clear that you expect a non-null pointer to be passed in and return early if not. This lets you not worry so much about invalid pointers.

1
  • Well, I thought about this pattern and find it absolutely reasonable. Sadly it looks not as clear as assert(buffer); Knowing that assert is active only for debug version, I sometimes wish to have a rt_assert(buffer); that throws an exception. The indentation of the return looks a little dangerous... BTW: your code snippet is a good illustration of my question about pointers for output.
    – Wolf
    Oct 5, 2015 at 10:10
1

It comes down to your observation If an output parameter is required.

The only place where a function signature is required to have an output parameter is when it is specified by an external API, and in such a case you just wrap the external API in something that ensures there is always a valid pointee.

Internally you avoid output parameters by extending the return type to be a composite of all of the "outs"

2
  • You mean, the only place where I'm not able to provide a non-mandatory pointer? True, but I'm not sure if your rule The only place where... is really applicable to all cases. What you suggest looks like: avoid output parameters in the functions of your own programs. True for new programs.
    – Wolf
    Oct 5, 2015 at 10:20
  • 1
    Yes, avoid output parameters, prefer composite return types, edited to make that clearer
    – Caleth
    Oct 5, 2015 at 11:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.