Commit a7c5f985 by Derek Mauro Committed by Copybara-Service

Fix absl::NoDestructor documentation about its use as a global

It is not possible to have a constant-initialized object of type
absl::NoDestructor<T>. Fix the documentation so that it doesn't
mention this possibility. Only recommend it use as a function-scope
static variable, and discourage its use as a global variable.
PiperOrigin-RevId: 647488395
Change-Id: Ifee052fce07609d3de72cddc30e86de67706cd91
parent d4cf6b71
...@@ -21,14 +21,13 @@ ...@@ -21,14 +21,13 @@
// such an object survives during program exit (and can be safely accessed at // such an object survives during program exit (and can be safely accessed at
// any time). // any time).
// //
// Objects of such type, if constructed safely and under the right conditions, // absl::NoDestructor<T> is useful when when a variable has static storage
// provide two main benefits over other alternatives: // duration but its type has a non-trivial destructor. Global constructors are
// // not recommended because of the C++'s static initialization order fiasco (See
// * Global objects not normally allowed due to concerns of destruction order // https://en.cppreference.com/w/cpp/language/siof). Global destructors are not
// (i.e. no "complex globals") can be safely allowed, provided that such // allowed due to similar concerns about destruction ordering. Using
// objects can be constant initialized. // absl::NoDestructor<T> as a function-local static prevents both of these
// * Function scope static objects can be optimized to avoid heap allocation, // issues.
// pointer chasing, and allow lazy construction.
// //
// See below for complete details. // See below for complete details.
...@@ -50,8 +49,8 @@ ABSL_NAMESPACE_BEGIN ...@@ -50,8 +49,8 @@ ABSL_NAMESPACE_BEGIN
// //
// NoDestructor<T> is a wrapper around an object of type T that behaves as an // NoDestructor<T> is a wrapper around an object of type T that behaves as an
// object of type T but never calls T's destructor. NoDestructor<T> makes it // object of type T but never calls T's destructor. NoDestructor<T> makes it
// safer and/or more efficient to use such objects in static storage contexts: // safer and/or more efficient to use such objects in static storage contexts,
// as global or function scope static variables. // ideally as function scope static variables.
// //
// An instance of absl::NoDestructor<T> has similar type semantics to an // An instance of absl::NoDestructor<T> has similar type semantics to an
// instance of T: // instance of T:
...@@ -62,9 +61,6 @@ ABSL_NAMESPACE_BEGIN ...@@ -62,9 +61,6 @@ ABSL_NAMESPACE_BEGIN
// `->`, `*`, and `get()`. // `->`, `*`, and `get()`.
// (Note that `const NoDestructor<T>` works like a pointer to const `T`.) // (Note that `const NoDestructor<T>` works like a pointer to const `T`.)
// //
// An object of type NoDestructor<T> should be defined in static storage:
// as either a global static object, or as a function scope static variable.
//
// Additionally, NoDestructor<T> provides the following benefits: // Additionally, NoDestructor<T> provides the following benefits:
// //
// * Never calls T's destructor for the object // * Never calls T's destructor for the object
...@@ -72,24 +68,7 @@ ABSL_NAMESPACE_BEGIN ...@@ -72,24 +68,7 @@ ABSL_NAMESPACE_BEGIN
// lazily constructed. // lazily constructed.
// //
// An object of type NoDestructor<T> is "trivially destructible" in the notion // An object of type NoDestructor<T> is "trivially destructible" in the notion
// that its destructor is never run. Provided that an object of this type can be // that its destructor is never run.
// safely initialized and does not need to be cleaned up on program shutdown,
// NoDestructor<T> allows you to define global static variables, since Google's
// C++ style guide ban on such objects doesn't apply to objects that are
// trivially destructible.
//
// Usage as Global Static Variables
//
// NoDestructor<T> allows declaration of a global object with a non-trivial
// constructor in static storage without needing to add a destructor.
// However, such objects still need to worry about initialization order, so
// such objects should be const initialized:
//
// // Global or namespace scope.
// constinit absl::NoDestructor<MyRegistry> reg{"foo", "bar", 8008};
//
// Note that if your object already has a trivial destructor, you don't need to
// use NoDestructor<T>.
// //
// Usage as Function Scope Static Variables // Usage as Function Scope Static Variables
// //
...@@ -115,6 +94,21 @@ ABSL_NAMESPACE_BEGIN ...@@ -115,6 +94,21 @@ ABSL_NAMESPACE_BEGIN
// return *x; // return *x;
// } // }
// //
// Usage as Global Static Variables
//
// NoDestructor<T> allows declaration of a global object of type T that has a
// non-trivial destructor since its destructor is never run. However, such
// objects still need to worry about initialization order, so such use is not
// recommended, strongly discouraged by the Google C++ Style Guide, and outright
// banned in Chromium.
// See https://google.github.io/styleguide/cppguide.html#Static_and_Global_Variables
//
// // Global or namespace scope.
// absl::NoDestructor<MyRegistry> reg{"foo", "bar", 8008};
//
// Note that if your object already has a trivial destructor, you don't need to
// use NoDestructor<T>.
//
template <typename T> template <typename T>
class NoDestructor { class NoDestructor {
public: public:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment