Skip to content

Commit db9c2e5

Browse files
authored
Merge pull request google#795 from zetafunction/cxx20-updates
Update C++ style guide for C++20.
2 parents 105acb7 + 901474a commit db9c2e5

File tree

1 file changed

+164
-39
lines changed

1 file changed

+164
-39
lines changed

cppguide.html

Lines changed: 164 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ <h2 id="Background" class="ignoreLink">Background</h2>
2121
code more bug-prone and harder to read and maintain.</p>
2222

2323
<p>The goal of this guide is to manage this complexity by
24-
describing in detail the dos and don'ts of writing C++ code
25-
. These rules exist to
24+
describing in detail the dos and don'ts of writing C++
25+
code. These rules exist to
2626
keep the code base manageable while still allowing
2727
coders to use C++ language features productively.</p>
2828

@@ -164,9 +164,8 @@ <h3 id="Goals">Goals of the Style Guide</h3>
164164

165165
<h2 id="C++_Version">C++ Version</h2>
166166

167-
<p>Currently, code should target C++17, i.e., should not use C++2x
168-
features, with the exception of <a href="#Designated_initializers">designated
169-
initializers</a>. The C++ version targeted by this guide will advance
167+
<p>Currently, code should target C++20, i.e., should not use C++23
168+
features. The C++ version targeted by this guide will advance
170169
(aggressively) over time.</p>
171170

172171

@@ -176,7 +175,7 @@ <h2 id="C++_Version">C++ Version</h2>
176175

177176
<div>
178177
<p>Consider portability to other environments before using features
179-
from C++14 and C++17 in your project.</p>
178+
from C++17 and C++20 in your project.</p>
180179
</div>
181180

182181
<h2 id="Header_Files">Header Files</h2>
@@ -686,6 +685,11 @@ <h3 id="Namespaces">Namespaces</h3>
686685
using ::absl::container_internal::ImplementationDetail;
687686
</pre>
688687
</li>
688+
689+
<li><p>Single-line nested namespace declarations
690+
691+
are preferred in new code, but are not required.</p>
692+
</li>
689693
</ul>
690694

691695
<a id="Unnamed_Namespaces_and_Static_Variables"></a>
@@ -940,14 +944,10 @@ <h4>Decision on initialization</h4>
940944

941945
<p>Constant initialization is always allowed. Constant initialization of
942946
static storage duration variables should be marked with <code>constexpr</code>
943-
or where possible the
944-
945-
946-
<a href="https://github.com/abseil/abseil-cpp/blob/03c1513538584f4a04d666be5eb469e3979febba/absl/base/attributes.h#L540">
947-
<code>ABSL_CONST_INIT</code></a>
948-
attribute. Any non-local static storage
947+
or <code>constinit</code></p>.
948+
Any non-local static storage
949949
duration variable that is not so marked should be presumed to have
950-
dynamic initialization, and reviewed very carefully.</p>
950+
dynamic initialization, and reviewed very carefully.
951951

952952
<p>By contrast, the following initializations are problematic:</p>
953953

@@ -1466,9 +1466,9 @@ <h3 id="Structs_vs._Classes">Structs vs. Classes</h3>
14661466
be present; however, these methods must not require or enforce any
14671467
invariants.</p>
14681468

1469-
<p>If more functionality or invariants are required, a
1470-
<code>class</code> is more appropriate. If in doubt, make
1471-
it a <code>class</code>.</p>
1469+
<p>If more functionality or invariants are required, or struct has wide visibility and expected to
1470+
evolve, then a <code>class</code> is more appropriate. If in doubt, make it a <code>class</code>.
1471+
</p>
14721472

14731473
<p>For consistency with STL, you can use
14741474
<code>struct</code> instead of <code>class</code> for
@@ -1678,17 +1678,23 @@ <h3 id="Operator_Overloading">Operator Overloading</h3>
16781678
because they must satisfy this rule for any possible template
16791679
arguments. If you define an operator, also define
16801680
any related operators that make sense, and make sure they
1681-
are defined consistently. For example, if you overload
1682-
<code>&lt;</code>, overload all the comparison operators,
1683-
and make sure <code>&lt;</code> and <code>&gt;</code> never
1684-
return true for the same arguments.</p>
1681+
are defined consistently.</p>
16851682

16861683
<p>Prefer to define non-modifying binary operators as
16871684
non-member functions. If a binary operator is defined as a
16881685
class member, implicit conversions will apply to the
16891686
right-hand argument, but not the left-hand one. It will
1690-
confuse your users if <code>a &lt; b</code> compiles but
1691-
<code>b &lt; a</code> doesn't.</p>
1687+
confuse your users if <code>a + b</code> compiles but
1688+
<code>b + a</code> doesn't.</p>
1689+
1690+
<p>For a type <code>T</code> whose values can be compared for
1691+
equality, define a non-member <code>operator==</code> and document when
1692+
two values of type <code>T</code> are considered equal.
1693+
If there is a single obvious notion of when a value <code>t1</code>
1694+
of type <code>T</code> is less than another such value <code>t2</code> then
1695+
you may also define <code>operator&lt;=&gt;</code>, which should be
1696+
consistent with <code>operator==</code>.
1697+
Prefer not to overload the other comparison and ordering operators.</p>
16921698

16931699
<p>Don't go out of your way to avoid defining operator
16941700
overloads. For example, prefer to define <code>==</code>,
@@ -2874,18 +2880,22 @@ <h4>Where to put the const</h4>
28742880
<code>const</code> first, we do not require it. But be
28752881
consistent with the code around you!</p>
28762882

2877-
<h3 id="Use_of_constexpr">Use of constexpr</h3>
2883+
<h3 id="Use_of_constexpr">Use of constexpr, constinit, and consteval</h3>
28782884

28792885
<p>Use <code>constexpr</code> to define true
2880-
constants or to ensure constant initialization.</p>
2886+
constants or to ensure constant initialization.
2887+
Use <code>constinit</code> to ensure constant
2888+
initialization for non-constant variables.
2889+
</p>
28812890

28822891
<p class="definition"></p>
28832892
<p> Some variables can be declared <code>constexpr</code>
28842893
to indicate the variables are true constants, i.e., fixed at
28852894
compilation/link time. Some functions and constructors
28862895
can be declared <code>constexpr</code> which enables them
28872896
to be used in defining a <code>constexpr</code>
2888-
variable.</p>
2897+
variable. Functions can be declared <code>consteval</code>
2898+
to restrict their use to compile time.</p>
28892899

28902900
<p class="pros"></p>
28912901
<p>Use of <code>constexpr</code> enables definition of
@@ -2906,9 +2916,11 @@ <h3 id="Use_of_constexpr">Use of constexpr</h3>
29062916
robust specification of the constant parts of an
29072917
interface. Use <code>constexpr</code> to specify true
29082918
constants and the functions that support their
2909-
definitions. Avoid complexifying function definitions to
2919+
definitions. <code>consteval</code> may be used for
2920+
code that must not be invoked at runtime.
2921+
Avoid complexifying function definitions to
29102922
enable their use with <code>constexpr</code>. Do not use
2911-
<code>constexpr</code> to force inlining.</p>
2923+
<code>constexpr</code> or <code>consteval</code> to force inlining.</p>
29122924

29132925
<h3 id="Integer_Types">Integer Types</h3>
29142926

@@ -2948,7 +2960,9 @@ <h3 id="Integer_Types">Integer Types</h3>
29482960
<code>int64_t</code>, etc. You should always use
29492961
those in preference to <code>short</code>, <code>unsigned
29502962
long long</code> and the like, when you need a guarantee
2951-
on the size of an integer. Of the built-in integer types, only
2963+
on the size of an integer. Prefer to omit the <code>std::</code>
2964+
prefix for these types, as the extra 5 characters do
2965+
not merit the added clutter. Of the built-in integer types, only
29522966
<code>int</code> should be used. When appropriate, you
29532967
are welcome to use standard type aliases like
29542968
<code>size_t</code> and <code>ptrdiff_t</code>.</p>
@@ -3148,7 +3162,6 @@ <h3 id="Preprocessor_Macros">Preprocessor Macros</h3>
31483162
<li>Prefer not using <code>##</code> to generate
31493163
function/class/variable names.</li>
31503164

3151-
31523165
</ul>
31533166

31543167
<p>Exporting macros from headers (i.e., defining them in a header
@@ -3525,8 +3538,8 @@ <h3 id="Designated_initializers">Designated Initializers</h3>
35253538

35263539
<p class="cons"></p>
35273540
<p>While designated initializers have long been part of the C standard and
3528-
supported by C++ compilers as an extension, only recently have they made it
3529-
into the C++ standard, being added as part of C++20.</p>
3541+
supported by C++ compilers as an extension, they were not supported by
3542+
C++ prior to C++20.</p>
35303543

35313544
<p>The rules in the C++ standard are stricter than in C and compiler extensions,
35323545
requiring that the designated initializers appear in the same order as the
@@ -3768,6 +3781,113 @@ <h3 id="Template_metaprogramming">Template Metaprogramming</h3>
37683781
be tweaked as necessary so that the error messages are understandable
37693782
and actionable from a user point of view.</p>
37703783

3784+
<h3 id="Concepts">Concepts and Constraints</h3>
3785+
3786+
<p>Use concepts sparingly.
3787+
In general, concepts and constraints should only be used in cases
3788+
where templates would have been used prior to C++20.
3789+
Avoid introducing new concepts in headers,
3790+
unless the headers are marked as internal to the library.
3791+
Do not define concepts that are not enforced by the compiler.
3792+
Prefer constraints over template metaprogramming, and
3793+
avoid the <code>template&lt;<i>Concept</i> T&gt;</code> syntax;
3794+
instead, use the <code>requires(<i>Concept&lt;T&gt;</i>)</code>
3795+
syntax.</p>
3796+
3797+
<p class="definition"></p>
3798+
<p>The <code>concept</code> keyword is a new mechanism for defining
3799+
requirements (such as type traits or interface specifications)
3800+
for a template parameter.
3801+
The <code>requires</code> keyword provides mechanisms for placing
3802+
anonymous constraints on templates and verifying that constraints
3803+
are satisfied at compile time.
3804+
Concepts and constraints are often used together, but can be
3805+
also used independently.</p>
3806+
3807+
<p class="pros"></p>
3808+
<ul>
3809+
<li>Concepts allow the compiler to generate much better error
3810+
messages when templates are involved, which can reduce confusion
3811+
and significantly improve the development experience.</li>
3812+
<li>Concepts can reduce the boilerplate necessary for defining
3813+
and using compile-time constraints, often increasing the clarity
3814+
of the resulting code.</li>
3815+
<li>Constraints provide some capabilities that are difficult to
3816+
achieve with templates and SFINAE techniques.</li>
3817+
</ul>
3818+
3819+
<p class="cons"></p>
3820+
<ul>
3821+
<li>As with templates, concepts can make code significantly more
3822+
complex and difficult to understand.</li>
3823+
<li>Concept syntax can be confusing to readers, as concepts
3824+
appear similar to class types at their usage sites.</li>
3825+
<li>Concepts, especially at API boundaries, increase code
3826+
coupling, rigidity, and ossification.</li>
3827+
<li>Concepts and constraints can replicate logic from a function
3828+
body, resulting in code duplication and increased maintenance
3829+
costs.</li>
3830+
<li>Concepts muddy the source of truth for their underlying
3831+
contracts, as they are standalone named entities that can be
3832+
utilized in multiple locations, all of which evolve separately
3833+
from each other.
3834+
This can cause the stated and implied requirements to diverge
3835+
over time.</li>
3836+
<li>Concepts and constraints affect overload resolution in novel
3837+
and non-obvious ways.</li>
3838+
<li>As with SFINAE, constraints make it harder to refactor code
3839+
at scale.</li>
3840+
</ul>
3841+
3842+
<p class="decision"></p>
3843+
<p>Predefined concepts in the standard library should be
3844+
preferred to type traits, when equivalent ones exist.
3845+
(e.g., if <code>std::is_integral_v</code> would have been used
3846+
before C++20, then <code>std::integral</code> should be used in
3847+
C++20 code.)
3848+
Similarly, prefer modern constraint syntax
3849+
(via <code>requires(<i>Condition</i>)</code>).
3850+
Avoid legacy template metaprogramming constructs
3851+
(such as <code>std::enable_if&lt;<i>Condition</i>&gt;</code>)
3852+
as well as the <code>template&lt;<i>Concept</i> T&gt;</code>
3853+
syntax.</p>
3854+
3855+
<p>Do not manually re-implement any existing concepts or traits.
3856+
For example, use
3857+
<code>requires(std::default_initializable&lt;T&gt;)</code>
3858+
instead of
3859+
<code>requires(requires { T v; })</code>
3860+
or the like.
3861+
3862+
</p><p>New <code>concept</code> declarations should be rare, and only
3863+
defined internally within a library, such that they are not
3864+
exposed at API boundaries.
3865+
More generally, do not use concepts or constraints in cases where
3866+
you wouldn't use their legacy template equivalents in C++17.
3867+
</p>
3868+
3869+
<p>Do not define concepts that duplicate the function body,
3870+
or impose requirements that would be insignificant or obvious
3871+
from reading the body of the code or the resulting error messages.
3872+
For example, avoid the following:
3873+
</p><pre class="badcode">template &lt;typename T&gt; // Bad - redundant with negligible benefit
3874+
concept Addable = std::copyable&lt;T&gt; &amp;&amp; requires(T a, T b) { a + b; };
3875+
template &lt;Addable T&gt;
3876+
T Add(T x, T y, T z) { return x + y + z; }
3877+
</pre>
3878+
Instead, prefer to leave code as an ordinary template unless
3879+
you can demonstrate that concepts result in significant
3880+
improvement for that particular case, such as in the resulting
3881+
error messages for a deeply nested or non-obvious
3882+
requirement.
3883+
3884+
<p>Concepts should be statically verifiable by the compiler.
3885+
Do not use any concept whose primary benefits would come from a
3886+
semantic (or otherwise unenforced) constraint.
3887+
Requirements that are unenforced at compile time should instead
3888+
be imposed via other mechanisms such as comments, assertions,
3889+
or tests.</p>
3890+
37713891
<h3 id="Boost">Boost</h3>
37723892

37733893
<p>Use only approved libraries from the Boost library
@@ -3955,9 +4075,10 @@ <h3 id="Aliases">Aliases</h3>
39554075

39564076
<p class="definition"></p>
39574077
<p>There are several ways to create names that are aliases of other entities:</p>
3958-
<pre>typedef Foo Bar;
3959-
using Bar = Foo;
3960-
using other_namespace::Foo;
4078+
<pre>using Bar = Foo;
4079+
typedef Foo Bar; // But prefer `using` in C++ code.
4080+
using ::other_namespace::Foo;
4081+
using enum MyEnumType; // Creates aliases for all enumerators in MyEnumType.
39614082
</pre>
39624083

39634084
<p>In new code, <code>using</code> is preferable to <code>typedef</code>,
@@ -4308,9 +4429,10 @@ <h3 id="Constant_Names">Constant Names</h3>
43084429

43094430
<p>All such variables with static storage duration (i.e., statics and globals,
43104431
see <a href="http://en.cppreference.com/w/cpp/language/storage_duration#Storage_duration">
4311-
Storage Duration</a> for details) should be named this way. This
4312-
convention is optional for variables of other storage classes, e.g., automatic
4313-
variables; otherwise the usual variable naming rules apply. For example:</p>
4432+
Storage Duration</a> for details) should be named this way, including those in templates where
4433+
different instantiations of the template may have different values. This convention is optional for
4434+
variables of other storage classes, e.g., automatic variables; otherwise the usual variable naming
4435+
rules apply. For example:</p>
43144436

43154437
<pre>void ComputeFoo(absl::string_view suffix) {
43164438
// Either of these is acceptable.
@@ -4515,7 +4637,7 @@ <h3 id="File_Comments">File Comments</h3>
45154637
New files should usually not contain copyright notice or
45164638
author line.</p>
45174639

4518-
<h3 id="Class_Comments">Class Comments</h3>
4640+
<h3 id="Class_Comments">Struct and Class Comments</h3>
45194641

45204642
<p>Every non-obvious class or struct declaration should have an
45214643
accompanying comment that describes what it is for and how it should
@@ -4532,6 +4654,8 @@ <h3 id="Class_Comments">Class Comments</h3>
45324654
};
45334655
</pre>
45344656

4657+
<h4 id="Class_Comments_Details">Class Comments</h4>
4658+
45354659
<p>The class comment should provide the reader with enough information to know
45364660
how and when to use the class, as well as any additional considerations
45374661
necessary to correctly use the class. Document the synchronization assumptions
@@ -4925,7 +5049,8 @@ <h3 id="Non-ASCII_Characters">Non-ASCII Characters</h3>
49255049
<p>When possible, avoid the <code>u8</code> prefix.
49265050
It has significantly different semantics starting in C++20
49275051
than in C++17, producing arrays of <code>char8_t</code>
4928-
rather than <code>char</code>.
5052+
rather than <code>char</code>, and will change again in C++23.
5053+
49295054

49305055
</p><p>You shouldn't use <code>char16_t</code> and
49315056
<code>char32_t</code> character types, since they're for

0 commit comments

Comments
 (0)