From 4b9c0c038971af8a7415c1ccaf435c5a78f9c73f Mon Sep 17 00:00:00 2001
From: Victor Costan Constant initialization is always allowed. Constant initialization of
static storage duration variables should be marked with package
specifier in the
+ .proto
file. See
+
+ Protocol Buffer Packages
+ for details.std
, including forward declarations of
@@ -955,7 +962,11 @@ Foo a[] = { Foo(1), Foo(2), Foo(3) }; // fine
constexpr
-where possible. Any non-local static storage
+or where possible the
+
+
+ABSL_CONST_INIT
+attribute. Any non-local static storage
duration variable that is not so marked should be presumed to have
dynamic initialization, and reviewed very carefully.
thread_local
variables that aren't declared inside a function
-must be initialized with a true compile-time constant. Prefer
+must be initialized with a true compile-time constant,
+and this must be enforced by using the
+
+
+ABSL_CONST_INIT
+attribute. Prefer
thread_local
over other ways of defining thread-local data.
thread_local
variables at class or namespace scope must be
initialized with a true compile-time constant (i.e. they must have no
- dynamic initialization).
thread_local
variables at class or namespace scope must be
+ annotated with
+
+
+ ABSL_CONST_INIT
+ (or constexpr
, but that should be rare):
-
+ABSL_CONST_INIT thread_local Foo foo = ...; +
thread_local
should be preferred over other mechanisms for
defining thread-local data.
Init()
method. Avoid Init()
methods on objects with
+or Init()
method as described in
+
+
+TotW #42
+.
+Avoid Init()
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
with correctly).
@@ -1226,7 +1254,10 @@ language treats it as one as far as explicit
is concerned.
expressive by eliminating the need to explicitly name a type
when it's obvious.
string_view
parameter takes the
+ place of separate overloads for string
and
+ const char*
.
std::cerr
or std::clog
+for diagnostic output, and the libraries in
+
+absl/strings
+or the equivalent are usually a
+better choice than std::stringstream
.
Avoid using streams for I/O that faces external users or handles untrusted data. Instead, find and use the appropriate @@ -2934,7 +2973,10 @@ localization, and security hardening.
If you do use streams, avoid the stateful parts of the
streams API (other than error state), such as imbue()
,
xalloc()
, and register_callback()
.
-Use explicit formatting functions rather than
+Use explicit formatting functions (see e.g.
+
+absl/strings
)
+rather than
stream manipulators or formatting flags to control formatting
details such as number base, precision, or padding.
printf
family. Instead use a library supporting typesafe numeric
formatting, such as
+
+ StrCat
+ or
+
+ Substitute
+ for fast simple conversions,
- std::ostream
.
+ or std::ostream
.
Unfortunately, the PRI
macros are the only portable way to
specify a conversion for the standard bitwidth typedefs (e.g.
@@ -3531,7 +3579,8 @@ instance).
new
+to new
and
+std::make_unique
commonly falls into this category, as does use of auto
in
a range-based loop over a container whose type is spelled out
nearby.Fall-through from one case label to
+another must be annotated using the
+ABSL_FALLTHROUGH_INTENDED;
macro (defined in
+absl/base/macros.h
).
+ABSL_FALLTHROUGH_INTENDED;
should be placed at a
+point of execution where a fall-through to the next case
+label occurs. A common exception is consecutive case
+labels without intervening code, in which case no
+annotation is needed.
switch (x) { + case 41: // No annotation needed here. + case 43: + if (dont_be_picky) { + // Use this instead of or along with annotations in comments. + ABSL_FALLTHROUGH_INTENDED; + } else { + CloseButNoCigar(); + break; + } + case 42: + DoSomethingSpecial(); + ABSL_FALLTHROUGH_INTENDED; + default: + DoSomethingGeneric(); + break; +} ++
Braces are optional for single-statement loops.