diff options
-rw-r--r-- | absl/base/no_destructor.h | 56 |
1 files changed, 25 insertions, 31 deletions
diff --git a/absl/base/no_destructor.h b/absl/base/no_destructor.h index 7b46456c..43b3540a 100644 --- a/absl/base/no_destructor.h +++ b/absl/base/no_destructor.h @@ -21,14 +21,13 @@ // such an object survives during program exit (and can be safely accessed at // any time). // -// Objects of such type, if constructed safely and under the right conditions, -// provide two main benefits over other alternatives: -// -// * Global objects not normally allowed due to concerns of destruction order -// (i.e. no "complex globals") can be safely allowed, provided that such -// objects can be constant initialized. -// * Function scope static objects can be optimized to avoid heap allocation, -// pointer chasing, and allow lazy construction. +// absl::NoDestructor<T> is useful when when a variable has static storage +// duration but its type has a non-trivial destructor. Global constructors are +// not recommended because of the C++'s static initialization order fiasco (See +// https://en.cppreference.com/w/cpp/language/siof). Global destructors are not +// allowed due to similar concerns about destruction ordering. Using +// absl::NoDestructor<T> as a function-local static prevents both of these +// issues. // // See below for complete details. @@ -50,8 +49,8 @@ ABSL_NAMESPACE_BEGIN // // 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 -// safer and/or more efficient to use such objects in static storage contexts: -// as global or function scope static variables. +// safer and/or more efficient to use such objects in static storage contexts, +// ideally as function scope static variables. // // An instance of absl::NoDestructor<T> has similar type semantics to an // instance of T: @@ -62,9 +61,6 @@ ABSL_NAMESPACE_BEGIN // `->`, `*`, and `get()`. // (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: // // * Never calls T's destructor for the object @@ -72,24 +68,7 @@ ABSL_NAMESPACE_BEGIN // lazily constructed. // // 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 -// 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>. +// that its destructor is never run. // // Usage as Function Scope Static Variables // @@ -115,6 +94,21 @@ ABSL_NAMESPACE_BEGIN // 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> class NoDestructor { public: |