From 193201734575f2568428b52aa6b9c470b5d1cdff Mon Sep 17 00:00:00 2001
From: Daniel Cheng
#include "base/logging.h"+
Headers should only be included using an angle-bracketed path if the library +requires you to do so. In particular, the following headers require angle +brackets:
+ +<stdlib.h>
+ and <string>
).<unistd.h>
+ and <windows.h>
).<Python.h>
).In dir/foo.cc
or
dir/foo_test.cc
, whose main
purpose is to implement or test the stuff in
@@ -425,9 +437,9 @@ as follows:
.h
extension), e.g., <unistd.h>
,
- <stdlib.h>
..h
extension, e.g., <unistd.h>
,
+ <stdlib.h>
, <Python.h>
.// Shorten access to some commonly used names (in a .h file). namespace librarian { -namespace impl { // Internal, not part of the API. +namespace internal { // Internal, not part of the API. namespace sidetable = ::pipeline_diagnostics::sidetable; -} // namespace impl +} // namespace internal inline void my_inline_function() { // namespace alias local to a function (or method). @@ -936,7 +948,7 @@ the formal language of the C++ standard. It means that the initializing expression is a constant expression, and if the object is initialized by a constructor call, then the constructor must be specified asconstexpr
, too: -struct Foo { constexpr Foo(int) {} }; +struct Foo { constexpr Foo(int) {} }; int n = 5; // Fine, 5 is a constant expression. Foo x(2); // Fine, 2 is a constant expression and the chosen constructor is constexpr. @@ -944,10 +956,10 @@ Foo a[] = { Foo(1), Foo(2), Foo(3) }; // FineConstant initialization is always allowed. Constant initialization of static storage duration variables should be marked with
. +orconstexpr
-orconstinit
constinit
. Any non-local static storage duration variable that is not so marked should be presumed to have -dynamic initialization, and reviewed very carefully. +dynamic initialization, and reviewed very carefully.By contrast, the following initializations are problematic:
@@ -1017,10 +1029,8 @@ does not make an observable difference. For example:@@ -1093,13 +1103,11 @@ get a particularly hard to diagnose use-after-free. initialized with a true compile-time constant (i.e., they must have no dynamic initialization). To enforce this,
thread_local
variables that aren't declared inside a function must be initialized with a true compile-time constant, and this must be enforced by using the - - - -ABSL_CONST_INIT
+ +constinit
attribute. Preferthread_local
over other ways of defining thread-local data.thread_local
variables at class or namespace scope must be annotated with - - - -ABSL_CONST_INIT
+ +constinit
(orconstexpr
, but that should be rare): -ABSL_CONST_INIT thread_local Foo foo = ...; +constinit thread_local Foo foo = ...;- -
thread_local
variables inside a function have no initialization @@ -1177,8 +1185,7 @@ for your code , terminating the program may be an appropriate error handling response. Otherwise, consider a factory function orInit()
method as described in -TotW #42 -. +TotW #42. AvoidInit()
methods on objects with no other states that affect which public methods may be called (semi-constructed objects of this form are particularly hard to work @@ -1445,8 +1452,6 @@ by making their constructors protected, by declaring their destructors protected or by giving them one or more pure virtual member functions. Prefer to avoid deriving from concrete classes.Structs vs. Classes
Use a
struct
only for passive objects that @@ -1794,7 +1799,7 @@ improve readability, and often provide the same or better performance.Prefer to return by value or, failing that, return by reference. -Avoid returning a pointer unless it can be null.
+Avoid returning a raw pointer unless it can be null.Parameters are either inputs to the function, outputs from the function, or both. Non-optional input parameters should usually be values @@ -1808,10 +1813,10 @@ optional outputs and optional input/output parameters.
-Avoid defining functions that require a
@@ -2255,10 +2260,10 @@ qualifier to methods), except as follows:const
reference parameter -to outlive the call, becauseconst
reference parameters bind -to temporaries. Instead, find a way to eliminate the lifetime requirement -(for example, by copying the parameter), or pass it byconst
+Avoid defining functions that require a reference parameter to outlive the call. +In some cases reference parameters can bind to temporaries, leading to lifetime +bugs. Instead, find a way to eliminate the lifetime requirement +(for example, by copying the parameter), or pass retained parameters by pointer and document the lifetime and non-null requirements.
Foo&&
and the other taking const Foo&
.
Usually the preferred solution is just to pass by value, but an overloaded
- pair of functions sometimes yields better performance and is sometimes
- necessary in generic code that needs to support a wide variety of types.
- As always: if you're writing more complicated code for the sake of
- performance, make sure you have evidence that it actually helps.void*
. Use this
only if you know what you are doing and you understand the aliasing
issues. Also, consider dereferencing the pointer (without a cast) and
- using absl::bit_cast
to cast the resulting value.
+ using std::bit_cast
to cast the resulting value.
- absl::bit_cast
to interpret the raw bits of a
+ std::bit_cast
to interpret the raw bits of a
value using a different type of the same size (a type pun), such as
interpreting the bits of a double
as
int64_t
.auto
can be qualified with const
, and can be
- used as part of a pointer or reference type, but it can't be used as a
- template argument. A rare variant of this syntax uses
+ used as part of a pointer or reference type, and (since C++17) as a
+ non-type template argument. A rare variant of this syntax uses
decltype(auto)
instead of auto
, in which case
the deduced type is the result of applying
decltype
@@ -4366,6 +4371,10 @@ using PropertiesMap = hash_map<UrlTableProperties *, std::string>;
enum class UrlTableError { ...
+The names of variables (including function parameters) and data members are @@ -5216,7 +5225,8 @@ double d = 1248e6;
float f = 1.0f; -float f2 = 1; // Also OK +float f2 = 1.0; // Also OK +float f3 = 1; // Also OK long double ld = -0.5L; double d = 1248.0e6;