Skip to content

Commit

Permalink
Update C++ style guide (#835)
Browse files Browse the repository at this point in the history
- Explicitly ban `long double`
- Use absl formatting libraries or `std::ostream` over printf-style
  functions.
- Portability: use serialization libraries instead of copying the
  in-memory representation.
- Update guidance to use `uintptr_t` (previously `intptr_t`) when
  working with pointers as integers.
- Ban C++20 modules.
- Ban coroutines (though this is expected to be temporary).
- Minor wording updates.
  • Loading branch information
zetafunction committed Sep 5, 2024
1 parent 57ea449 commit 8c4da23
Showing 1 changed file with 71 additions and 58 deletions.
129 changes: 71 additions & 58 deletions cppguide.html
Original file line number Diff line number Diff line change
Expand Up @@ -3026,70 +3026,53 @@ <h4>On Unsigned Integers</h4>
representing bitfields or modular arithmetic). Do not use an unsigned
type merely to assert that a variable is non-negative.</p>

<h3 id="64-bit_Portability">64-bit Portability</h3>
<h3 id="Floating-Point_Types">Floating-Point Types</h3>

<p>Code should be 64-bit and 32-bit friendly. Bear in mind
problems of printing, comparisons, and structure alignment.</p>

<ul>
<li>
<p>Correct portable <code>printf()</code> conversion specifiers for
some integral typedefs rely on macro expansions that we find unpleasant to
use and impractical to require (the <code>PRI</code> macros from
<code>&lt;cinttypes&gt;</code>). Unless there is no reasonable alternative
for your particular case, try to avoid or even upgrade APIs that rely on the
<code>printf</code> family. Instead use a library supporting typesafe numeric
formatting, such as


<a href="https://github.com/abseil/abseil-cpp/blob/master/absl/strings/str_cat.h"><code>StrCat</code></a>

or
<p>Of the built-in C++ floating-point types, the only ones used
are <code>float</code> and
<code>double</code>. You may assume that these types represent IEEE-754 binary32
and binary64, respectively.</p>

<p>Do not use <code>long double</code>, as it gives non-portable
results.</p>

<a href="https://github.com/abseil/abseil-cpp/blob/master/absl/strings/substitute.h"><code>Substitute</code></a>
<a id="64-bit_Portability"></a>
<h3 id="Architecture_Portability">Architecture Portability</h3>

for fast simple conversions,
<p>Write architecture-portable code. Do not rely on CPU features specific to a
single processor.</p>

or <a href="#Streams"><code>std::ostream</code></a>.</p>

<p>Unfortunately, the <code>PRI</code> macros are the only portable way to
specify a conversion for the standard bitwidth typedefs (e.g.,
<code>int64_t</code>, <code>uint64_t</code>, <code>int32_t</code>,
<code>uint32_t</code>, etc).
Where possible, avoid passing arguments of types specified by bitwidth
typedefs to <code>printf</code>-based APIs. Note that it is acceptable
to use typedefs for which printf has dedicated length modifiers, such as
<code>size_t</code> (<code>z</code>),
<code>ptrdiff_t</code> (<code>t</code>), and
<code>maxint_t</code> (<code>j</code>).</p>
<ul>
<li>When printing values, use type-safe numeric formatting libraries like
<a href="https://github.com/abseil/abseil-cpp/blob/master/absl/strings/str_cat.h"><code>absl::StrCat</code></a>,
<a href="https://github.com/abseil/abseil-cpp/blob/master/absl/strings/substitute.h"><code>absl::Substitute</code></a>,
<a href="https://github.com/abseil/abseil-cpp/blob/master/absl/strings/str_format.h"><code>absl::StrFormat</code></a>,
or <a href="#Streams"><code>std::ostream</code></a> instead of the
<code>printf</code> family of functions.</li>

<li>When moving structured data into or out of your process, encode it using a
serialization library like
<a href="https://protobuf.dev/">Protocol
Buffers</a> rather than copying the in-memory representation around.
</li>

<li>Remember that <code>sizeof(void *)</code> !=
<code>sizeof(int)</code>. Use <code>intptr_t</code> if
you want a pointer-sized integer.</li>

<li>You may need to be careful with structure
alignments, particularly for structures being stored on
disk. Any class/structure with a <code>int64_t</code>/<code>uint64_t</code>
member will by default end up being 8-byte aligned on a
64-bit system. If you have such structures being shared
on disk between 32-bit and 64-bit code, you will need
to ensure that they are packed the same on both
architectures.
Most compilers offer a way to
alter structure alignment. For gcc, you can use
<code>__attribute__((packed))</code>. MSVC offers
<code>#pragma pack()</code> and
<code>__declspec(align())</code>.</li>
<li>If you need to work with memory addresses as integers, store them in
<code>uintptr_t</code>s rather than <code>uint32_t</code>s or
<code>uint64_t</code>s.</li>

<li>
<p>Use <a href="#Casting">braced-initialization</a> as needed to create
64-bit constants. For example:</p>
Use <a href="#Casting">braced-initialization</a> as needed to create
64-bit constants. For example:
<pre>int64_t my_value{0x123456789};
uint64_t my_mask{uint64_t{3} &lt;&lt; 48};
</pre>
</li>

<li>Use portable <a href="#Floating-Point_Types">floating point types</a>;
avoid <code>long double</code>.</li>

<li>Use portable <a href="#Integer_Types">integer types</a>; avoid
<code>short</code>, <code>long</code>, and <code>long long</code>.</li>
</ul>

<h3 id="Preprocessor_Macros">Preprocessor Macros</h3>
Expand Down Expand Up @@ -3893,6 +3876,37 @@ <h3 id="Concepts">Concepts and Constraints</h3>
be imposed via other mechanisms such as comments, assertions,
or tests.</p>

<h3 id="modules">C++20 modules</h3>

<p>Do not use C++20 Modules.</p>

<p>C++20 introduces "modules", a new language feature designed as an
alternative to textual inclusion of header files. It introduces three
new keywords to support
this: <code>module</code>, export,
and <code>import</code>.

</p><p>Modules are a big shift in how C++ is written and compiled, and we
are still assessing how they may fit into Google's C++ ecosystem in
the future. Furthermore, they are not currently well-supported by our
build-systems, compilers, and other tooling, and need further
exploration as to the best-practices when writing and using them.</p>



<h3 id="coroutines">Coroutines</h3>

<p>Do not use coroutines (yet).</p>

<p>Do not include the <code>&lt;coroutine&gt;</code> header,
or use the <code>co_await</code>, <code>co_yield</code>,
or <code>co_return</code> keywords.</p>

<p>NOTE: this ban is expected to be temporary, while further
guidance is being developed.

</p>

<h3 id="Boost">Boost</h3>

<p>Use only approved libraries from the Boost library
Expand Down Expand Up @@ -3997,11 +4011,11 @@ <h3 id="Boost">Boost</h3>



<h3 id="Other_Features"><a id="C++11">Other C++ Features</a></h3>
<h3 id="Disallowed_Stdlib">Disallowed standard library features</h3>


<p>As with <a href="#Boost">Boost</a>, some modern C++
extensions encourage coding practices that hamper
library functionality encourages coding practices that hamper
readability—for example by removing
checked redundancy (such as type names) that may be
helpful to readers, or by encouraging template
Expand All @@ -4010,8 +4024,7 @@ <h3 id="Other_Features"><a id="C++11">Other C++ Features</a></h3>
and conversion costs.</p>

<p class="decision"></p>
<p>In addition to what's described in the rest of the style
guide, the following C++ features may not be used:</p>
<p>The following C++ standard library features may not be used:</p>

<ul>

Expand Down Expand Up @@ -4330,8 +4343,8 @@ <h3 id="General_Naming_Rules">General Naming Rules</h3>
<li><code>myusefulclass_test.cc // _unittest and _regtest are deprecated.</code></li>
</ul>

<p>C++ files should end in <code>.cc</code> and header files should end in
<code>.h</code>. Files that rely on being textually included at specific points
<p>C++ files should have a <code>.cc</code> filename extension, and header files
should have a <code>.h</code> extension. Files that rely on being textually included at specific points
should end in <code>.inc</code> (see also the section on
<a href="#Self_contained_Headers">self-contained headers</a>).</p>

Expand Down Expand Up @@ -5917,7 +5930,7 @@ <h2 id="Exceptions_to_the_Rules">Exceptions to the Rules</h2>


<div>
<h3 id="Existing_Non-conformant_Code">Existing Non-conformant Code</h3>
<h3 id="Existing_Non-conformant_Code" class="no-toc">Existing Non-conformant Code</h3>

<p>You may diverge from the rules when dealing with code that
does not conform to this style guide.</p>
Expand Down

0 comments on commit 8c4da23

Please sign in to comment.