1 // Copyright 2017 The Abseil Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // https://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 // 15 // ----------------------------------------------------------------------------- 16 // kConstInit 17 // ----------------------------------------------------------------------------- 18 // 19 // A constructor tag used to mark an object as safe for use as a global 20 // variable, avoiding the usual lifetime issues that can affect globals. 21 22 #ifndef ABSL_BASE_CONST_INIT_H_ 23 #define ABSL_BASE_CONST_INIT_H_ 24 25 #include "absl/base/config.h" 26 27 // In general, objects with static storage duration (such as global variables) 28 // can trigger tricky object lifetime situations. Attempting to access them 29 // from the constructors or destructors of other global objects can result in 30 // undefined behavior, unless their constructors and destructors are designed 31 // with this issue in mind. 32 // 33 // The normal way to deal with this issue in C++11 is to use constant 34 // initialization and trivial destructors. 35 // 36 // Constant initialization is guaranteed to occur before any other code 37 // executes. Constructors that are declared 'constexpr' are eligible for 38 // constant initialization. You can annotate a variable declaration with the 39 // ABSL_CONST_INIT macro to express this intent. For compilers that support 40 // it, this annotation will cause a compilation error for declarations that 41 // aren't subject to constant initialization (perhaps because a runtime value 42 // was passed as a constructor argument). 43 // 44 // On program shutdown, lifetime issues can be avoided on global objects by 45 // ensuring that they contain trivial destructors. A class has a trivial 46 // destructor unless it has a user-defined destructor, a virtual method or base 47 // class, or a data member or base class with a non-trivial destructor of its 48 // own. Objects with static storage duration and a trivial destructor are not 49 // cleaned up on program shutdown, and are thus safe to access from other code 50 // running during shutdown. 51 // 52 // For a few core Abseil classes, we make a best effort to allow for safe global 53 // instances, even though these classes have non-trivial destructors. These 54 // objects can be created with the absl::kConstInit tag. For example: 55 // ABSL_CONST_INIT absl::Mutex global_mutex(absl::kConstInit); 56 // 57 // The line above declares a global variable of type absl::Mutex which can be 58 // accessed at any point during startup or shutdown. global_mutex's destructor 59 // will still run, but will not invalidate the object. Note that C++ specifies 60 // that accessing an object after its destructor has run results in undefined 61 // behavior, but this pattern works on the toolchains we support. 62 // 63 // The absl::kConstInit tag should only be used to define objects with static 64 // or thread_local storage duration. 65 66 namespace absl { 67 ABSL_NAMESPACE_BEGIN 68 69 enum ConstInitType { 70 kConstInit, 71 }; 72 73 ABSL_NAMESPACE_END 74 } // namespace absl 75 76 #endif // ABSL_BASE_CONST_INIT_H_ 77