On 07/12/2018 04:41 AM, Richard Sandiford wrote:
Following on from:
https://gcc.gnu.org/ml/gcc-patches/2018-07/msg00603.html
this patch is an RFC to mention references in the C++ coding conventions.
It allows const references anywhere they're useful but only allows
non-constant references in contexts that conform to a standard
interface, or when returning a reference to something that is known
to be nonnull.
It looks like there are still very few public functions that use
non-constant references. If the patch is OK, I'll volunteer to
change them.
Thanks,
Richard
Index: htdocs/codingconventions.html
===================================================================
RCS file: /cvs/gcc/wwwdocs/htdocs/codingconventions.html,v
retrieving revision 1.81
diff -u -p -r1.81 codingconventions.html
--- htdocs/codingconventions.html 2 Jun 2018 21:16:09 -0000 1.81
+++ htdocs/codingconventions.html 12 Jul 2018 10:05:12 -0000
@@ -57,6 +57,7 @@ the conventions separately from any othe
<li><a href="#Over_Func">Overloading Functions</a></li>
<li><a href="#Over_Oper">Overloading Operators</a></li>
<li><a href="#Default">Default Arguments</a></li>
+ <li><a href="#NonConst_Ref">References</a></li>
<li><a href="#Cxx_Inlining">Inlining Functions</a></li>
<li><a href="#Template_Use">Templates</a></li>
<li><a href="#Namespace_Use">Namespaces</a></li>
@@ -996,6 +997,44 @@ Virtual functions should not have defaul
</p>
+<h4><a name="NonConst_Ref">References</a></h4>
+
+<p>
+Const references can be used freely. They are a useful way of reducing
+unnecessary copying or avoiding an impossible copy.
+</p>
+
+<p>
+Only use non-constant references in the following situations:
+</p>
+
+<ul>
+<li>when they are necessary to conform to a standard interface, such as
+the first argument to a non-member <code>operator+=</code></li>
+<li>in a return value, when providing access to something that is known
+to be nonnull</li>
+</ul>
+
+<p>
+In other situations the convention is to use pointers instead.
+</p>
As always, there are pluses and minuses. You mention the pluses
and I don't disagree with them, though perhaps not strongly enough
to feel that it justifies making it a hard and fast rule in
a codebase as large (and as inconsistent) as GCC.
Others have already mentioned some of the downsides but let me
add my own $0.02. I'm not sure that they rise to the level of
overwhelming the advantages but they don't make it a slam dunk
either.
Pass by pointer means that the function (or its reader) needs
to worry about the argument being null. It's often on my mind
when I don't see it documented. This could be mitigated to
an extent by using the nonnull attribute to help us avoid
(both visually and via -Wnonnull-compare) pointless tests for
null in the body of the function. But it still means I have
to check the declaration to confirm that. Pass by reference
doesn't suffer from these problems.
I agree that outside of function arguments, pointers are best
avoided where possible in favor of references (ideally const
references where applicable). It makes it clear that a const
reference implies the object is immutable. Someday GCC might
even be able to take advantage of it for optimization.
All in all, I'm ambivalent about the value of the convention.
I suspect it will be another hoop for new contributors (and
some of the rest of us) to jump through that will not lead
to significant improvements. I think there are other, more
interesting, opportunities to improve things.
Martin
PS Rather than documenting a convention and leaving it to
others to remember to enforce, I would suggest to implement
a warning to help us achieve consistency and avoid wasting
time going back and forth about it in code reviews.
+
+<blockquote>
+<pre><code>HOST_WIDE_INT do_arith (..., bool *overflow); // OK
+HOST_WIDE_INT do_arith (..., bool &overflow); // Please avoid
+
+int *elt = &array[i]; // OK
+int &elt = array[i]; // Please avoid
+</code></pre></blockquote>
+
+<p>
+There are two main reasons for this restriction. The first is to avoid
+an inconsistency with the large body of older (pre-C++) code that uses
+the pointer convention. The second is to maintain a visual distinction
+between the arguments that a function does modify and the arguments that
+it doesn't.
+</p>
+
<h4><a name="Cxx_Inlining">Inlining Functions</a></h4>
<p>