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?

Wolf
  • 640

3 Answers3

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.

Doc Brown
  • 218,378
Josh Kelley
  • 11,131
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.

ratchet freak
  • 25,986
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"

Caleth
  • 12,190