Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qglobalstatic.qdoc
Go to the documentation of this file.
1// Copyright (C) 2021 Intel Corporation.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
3
4/*!
5 \macro Q_GLOBAL_STATIC(Type, VariableName, ...)
6 \since 5.1
7 \relates QGlobalStatic
8
9 Creates a global and static object of type \l QGlobalStatic, of name \a
10 VariableName and that behaves as a pointer to \a Type. The object created
11 by Q_GLOBAL_STATIC initializes itself on the first use, which means that it
12 will not increase the application or the library's load time. Additionally,
13 the object is initialized in a thread-safe manner on all platforms.
14
15 Since Qt 6.3, this macro admits variadic arguments, which are used to
16 initialize the object, thus making the need for \l
17 Q_GLOBAL_STATIC_WITH_ARGS unnecessary. Please note the arguments do not
18 require an extra set of parentheses, unlike the older macro.
19
20 The typical use of this macro is as follows, in a global context (that is,
21 outside of any function bodies):
22
23 \code
24 Q_GLOBAL_STATIC(MyType, staticType)
25 \endcode
26
27 This macro is intended to replace global static objects that are not POD
28 (Plain Old Data, or in C++11 terms, not made of a trivial type), hence the
29 name. For example, the following C++ code creates a global static:
30
31 \code
32 static MyType staticType;
33 \endcode
34
35 Compared to Q_GLOBAL_STATIC, and assuming that \c MyType is a class or
36 struct that has a constructor, a destructor, or is otherwise non-POD, the
37 above has the following drawbacks:
38
39 \list
40 \li it requires load-time initialization of \c MyType (that is, the
41 default constructor for \c MyType is called when the library or
42 application is loaded);
43
44 \li the type will be initialized even if it is never used;
45
46 \li the order of initialization and destruction among different
47 translation units is not determined, leading to possible uses before
48 initialization or after destruction;
49 \endlist
50
51 The Q_GLOBAL_STATIC macro solves all of the above problems by guaranteeing
52 thread-safe initialization on first use and allowing the user to query for
53 whether the type has already been destroyed, to avoid the
54 use-after-destruction problem (see QGlobalStatic::isDestroyed()).
55
56 \section1 Constructor and Destructor
57
58 For Q_GLOBAL_STATIC, the type \c Type must be publicly
59 default-constructible and publicly destructible. For
60 Q_GLOBAL_STATIC_WITH_ARGS(), there must be a public constructor that
61 matches the arguments passed.
62
63 It is not possible to use Q_GLOBAL_STATIC with types that have protected or
64 private default constructors or destructors (for Q_GLOBAL_STATIC_WITH_ARGS(),
65 a protected or private constructor matching the arguments). If the type in
66 question has those members as protected, it is possible to overcome the
67 issue by deriving from the type and creating public a constructor and
68 destructor. If the type has them as private, a friend declaration is
69 necessary before deriving.
70
71 For example, the following is enough to create \c MyType based on a
72 previously-defined \c MyOtherType which has a protected default constructor
73 and/or a protected destructor (or has them as private, but that defines \c
74 MyType as a friend).
75
76 \code
77 class MyType : public MyOtherType { };
78 Q_GLOBAL_STATIC(MyType, staticType)
79 \endcode
80
81 No body for \c MyType is required since the destructor is an implicit
82 member and so is the default constructor if no other constructors are
83 defined. For use with Q_GLOBAL_STATIC_WITH_ARGS(), however, a suitable
84 constructor body is necessary:
85
86 \code
87 class MyType : public MyOtherType
88 {
89 public:
90 MyType(int i) : MyOtherType(i) {}
91 };
92 Q_GLOBAL_STATIC_WITH_ARGS(MyType, staticType, (42))
93 \endcode
94
95 Alternatively, if the compiler supports C++11 inheriting constructors, one could write:
96
97 \code
98 class MyType : public MyOtherType
99 {
100 public:
101 using MyOtherType::MyOtherType;
102 };
103 Q_GLOBAL_STATIC_WITH_ARGS(MyType, staticType, (42))
104 \endcode
105
106 \section1 Placement
107
108 The Q_GLOBAL_STATIC macro creates a type that is necessarily static, at the
109 global scope. It is not possible to place the Q_GLOBAL_STATIC macro inside
110 a function (doing so will result in compilation errors).
111
112 More importantly, this macro should be placed in source files, never in
113 headers. Since the resulting object is has static linkage, if the macro is
114 placed in a header and included by multiple source files, the object will
115 be defined multiple times and will not cause linking errors. Instead, each
116 translation unit will refer to a different object, which could lead to
117 subtle and hard-to-track errors.
118
119 \section1 Non-recommended uses
120
121 Note that the macro is not recommended for use with types that are POD or
122 that have C++11 constexpr constructors (trivially constructible and
123 destructible). For those types, it is still recommended to use regular
124 static, whether global or function-local.
125
126 This macro will work, but it will add unnecessary overhead.
127
128 \section1 Reentrancy, Thread-safety, Deadlocks, and Exception-safety on Construction
129
130 The Q_GLOBAL_STATIC macro creates an object that initializes itself on
131 first use in a thread-safe manner: if multiple threads attempt to
132 initialize the object at the same time, only one thread will proceed to
133 initialize, while all other threads wait for completion.
134
135 If the initialization process throws an exception, the initialization is
136 deemed not complete and will be attempted again when control reaches any
137 use of the object. If there are any threads waiting for initialization, one
138 of them will be woken up to attempt to initialize.
139
140 The macro makes no guarantee about reentrancy from the same thread. If the
141 global static object is accessed directly or indirectly from inside the
142 constructor, a deadlock will surely happen.
143
144 In addition, if two Q_GLOBAL_STATIC objects are being initialized on two
145 different threads and each one's initialization sequence accesses the
146 other, a deadlock might happen. For that reason, it is recommended to keep
147 global static constructors simple or, failing that, to ensure that there's
148 no cross-dependency of uses of global static during construction.
149
150 \section1 Destruction
151
152 If the object is never used during the lifetime of the program, aside from
153 the QGlobalStatic::exists() and QGlobalStatic::isDestroyed() functions, the
154 contents of type \a Type will not be created and there will not be any
155 exit-time operation.
156
157 If the object is created, it will be destroyed at exit-time, similar to the
158 C \c atexit function. On most systems, in fact, the destructor will also be
159 called if the library or plugin is unloaded from memory before exit.
160
161 Since the destruction is meant to happen at program exit, no thread-safety
162 is provided. This includes the case of plugin or library unload. In
163 addition, since destructors are not supposed to throw exceptions, no
164 exception safety is provided either.
165
166 However, reentrancy is permitted: during destruction, it is possible to
167 access the global static object and the pointer returned will be the same
168 as it was before destruction began. After the destruction has completed,
169 accessing the global static object is not permitted, except as noted in the
170 \l QGlobalStatic API.
171
172 \omit
173 \section1 Compatibility with Qt 4 and Qt 5.0
174
175 This macro, in its current behavior, was introduced in Qt 5.1. Prior to
176 that version, Qt had another macro with the same name that was private API.
177 This section is not meant to document how to use Q_GLOBAL_STATIC in those
178 versions, but instead to serve as a porting guide for Qt code that used
179 those macros.
180
181 The Qt 4 Q_GLOBAL_STATIC macro differed in behavior in the following ways:
182
183 \list
184 \li the object created was not of type \l QGlobalStatic, but instead
185 it was a function that returned a pointer to \a Type; that means the
186 \l QGlobalStatic API was not present;
187
188 \li the initialization was thread-safe, but not guaranteed to be
189 unique: instead, if N threads tried to initialize the object at the
190 same time, N objects would be created on the heap and N-1 would be
191 destroyed;
192
193 \li the object was always created on the heap.
194 \endlist
195
196 \section1 Implementation Details
197
198 Q_GLOBAL_STATIC is implemented by creating a type called \c Q_QGS_NAME
199 where \c NAME is the name of the variable the user passed to the macro,
200 inside an unnamed namespace, and a \c static variable of \l QGlobalStatic
201 type, named \c NAME. The use of unnamed namespaces forces the compiler to emit
202 non-exported symbols, often local to the translation unit, and this
203 propagates to the \l QGlobalStatic template instantiation that uses such
204 types. Additionally, because the type is used only for one variable,
205 there's effectively no difference between static and non-static data
206 members.
207
208 The "QGS" type is a \c struct containing a \c typedef to \a TYPE and a
209 static member function that receives a pointer to storage suitable to hold
210 an instance of \a TYPE. It will initialize the storage using a placement \c
211 new and the variadic arguments.
212
213 The majority of the work is done by the public \l QGlobalStatic class and
214 the private \c QtGlobalStatic::Holder class. The \c Holder union has a
215 single non-static member of type \a TYPE, but because this is a union, its
216 construction and destruction are explicitly controlled in the Holder's
217 constructor and destructor. The constructor calls the "QGS" type's static
218 member function with a pointer to this member so it can be initialized
219 and the destructor calls the type's destructor. The \c{Holder} type is
220 therefore neither trivially constructible nor trivially destructible. It is
221 used as a function-local \c static so its initialization is thread-safe due
222 to C++11's requirement that such variables be thread-safely initialized.
223
224 Additionally, both the constructor and destructor modify a guard variable
225 after construction and before destruction, respectively. The guard variable
226 is implemented as a \c {static inline} member instead of a non-static
227 member so the compiler and linker are free to place this variable in memory
228 far from the actual object. This way, if we wanted to, we could mark it
229 aligned-to-cacheline in the future to prevent false sharing.
230
231 The guard variable can assume the following values:
232
233 \list
234 \li -2: object was once initialized but has been destroyed already;
235 \li -1: object was initialized and is still valid;
236 \li 0: object was not initialized yet;
237 \li +1: object is being initialized and any threads encountering this
238 value must wait for completion (not used in the current implementation).
239 \endlist
240
241 Collectively, all positive values indicate that the initialization is
242 progressing and must be waited on, whereas all negative values indicate
243 that the initialization has terminated and must not be attempted again.
244 Positive values are not used in the current implementation, but were in
245 earlier versions. They could be used again in the future.
246
247 The QGlobalStatic::exists() and QGlobalStatic::isDestroyed() functions
248 operate solely on the guard variable: the former returns \c true if the guard
249 is negative, whereas the latter returns \c true only if it is -2.
250
251 \endomit
252
253 \sa Q_GLOBAL_STATIC_WITH_ARGS(), Q_APPLICATION_STATIC(), QGlobalStatic
254*/
255
256/*!
257 \macro Q_GLOBAL_STATIC_WITH_ARGS(Type, VariableName, Arguments)
258 \since 5.1
259 \obsolete
260 \relates QGlobalStatic
261
262 Creates a global and static object of type \l QGlobalStatic, of name \a
263 VariableName, initialized by the arguments \a Arguments and that behaves as
264 a pointer to \a Type. The object created by Q_GLOBAL_STATIC_WITH_ARGS
265 initializes itself on the first use, which means that it will not increase
266 the application or the library's load time. Additionally, the object is
267 initialized in a thread-safe manner on all platforms.
268
269 The typical use of this macro is as follows, in a global context (that is,
270 outside of any function bodies):
271
272 \code
273 Q_GLOBAL_STATIC_WITH_ARGS(MyType, staticType, (42, "Hello", "World"))
274 \endcode
275
276 The \a Arguments macro parameter must always include the parentheses or, if
277 C++11 uniform initialization is allowed, the braces. The above call is
278 equivalent to
279
280 \code
281 Q_GLOBAL_STATIC(MyType, staticType, 42, "Hello", "World")
282 \endcode
283
284 Aside from the actual initialization of the contents with the supplied
285 arguments, this macro behaves identically to Q_GLOBAL_STATIC(). Please
286 see that macro's documentation for more information.
287
288 \sa Q_GLOBAL_STATIC(), QGlobalStatic
289*/
290
291/*!
292 \class QGlobalStatic
293 \threadsafe
294 \inmodule QtCore
295 \since 5.1
296 \brief The QGlobalStatic class is used to implement a global static object.
297
298 The QGlobalStatic class is the front-end API exported when
299 Q_GLOBAL_STATIC() is used. See the documentation for the macro for a
300 discussion on when to use it and its requirements.
301
302 Normally, you will never use this class directly, but instead you will use
303 the Q_GLOBAL_STATIC() or Q_GLOBAL_STATIC_WITH_ARGS() macros, as
304 follows:
305
306 \code
307 Q_GLOBAL_STATIC(MyType, staticType)
308 \endcode
309
310 The above example creates an object of type QGlobalStatic called \c
311 staticType. After the above declaration, the \c staticType object may be
312 used as if it were a pointer, guaranteed to be initialized exactly once. In
313 addition to the use as a pointer, the object offers two methods to
314 determine the current status of the global: exists() and isDestroyed().
315
316 \sa Q_GLOBAL_STATIC(), Q_GLOBAL_STATIC_WITH_ARGS()
317*/
318
319/*!
320 \typedef QGlobalStatic::Type
321
322 This type is equivalent to the \c Type parameter passed to the
323 Q_GLOBAL_STATIC() or Q_GLOBAL_STATIC_WITH_ARGS() macros. It is used in the
324 return types of some functions.
325*/
326
327/*!
328 \fn template <typename Holder> bool QGlobalStatic<Holder>::isDestroyed() const
329
330 This function returns \c true if the global static object has already
331 completed destruction (that is, if the destructor for the type has already
332 returned). In specific, note that this function returns \c false if
333 the destruction is still in progress.
334
335 Once this function has returned true once, it will never return
336 false again until either the program is restarted or the plugin or library
337 containing the global static is unloaded and reloaded.
338
339 This function is safe to call at any point in the program execution: it
340 cannot fail and cannot cause a deadlock. Additionally, it will not cause
341 the contents to be created if they have not yet been created.
342
343 This function is useful in code that may be executed at program shutdown,
344 to determine whether the contents may still be accessed or not.
345
346 \omit
347 Due to the non-atomic nature of destruction, it's possible that
348 QGlobalStatic::isDestroyed might return false for a short time after the
349 destructor has finished. However, since the destructor is only run in an
350 environment where concurrent multithreaded access is impossible, no one can
351 see that state. (omitted because it's useless information)
352 \endomit
353
354 \sa exists()
355*/
356
357/*!
358 \fn template <typename Holder> bool QGlobalStatic<Holder>::exists() const
359
360 This function returns \c true if the global static object has already
361 completed initialization (that is, if the constructor for the type has
362 already returned). In specific, note that this function returns \c false if
363 the initialization is still in progress.
364
365 Once this function has returned true once, it will never return false again
366 until either the program is restarted or the plugin or library containing
367 the global static is unloaded and reloaded.
368
369 This function is safe to call at any point in the program execution: it
370 cannot fail and cannot cause a deadlock. Additionally, it will not cause
371 the contents to be created if they have not yet been created.
372
373 This function is useful if one can determine the initial conditions of the
374 global static object and would prefer to avoid a possibly expensive
375 construction operation.
376
377 For example, in the following code sample, this function is used to
378 short-circuit the creation of the global static called \c globalState and
379 returns a default value:
380
381 \code
382 Q_GLOBAL_STATIC(MyType, globalState)
383 QString someState()
384 {
385 if (globalState.exists())
386 return globalState->someState;
387 return QString();
388 }
389 \endcode
390
391 \b{Thread-safety notice:} this function is thread-safe in the sense that it
392 may be called from any thread at any time and will always return a valid
393 reply. But due to the non-atomic nature of construction, this function may
394 return false for a short time after the construction has completed.
395
396 \b{Memory ordering notice:} this function does not impose any memory
397 ordering guarantees. That is instead provided by the accessor functions
398 that return the pointer or reference to the contents. If you bypass the
399 accessor functions and attempt to access some global state set by the
400 constructor, be sure to use the correct memory ordering semantics provided
401 by \l QAtomicInt or \l QAtomicPointer.
402
403 \sa isDestroyed()
404*/
405
406/*!
407 \keyword qglobalstatic-operator-type-ptr
408 \fn template <typename Holder> QGlobalStatic<Holder>::operator Type*()
409
410 This function returns the address of the contents of this global static. If
411 the contents have not yet been created, they will be created thread-safely
412 by this function. If the contents have already been destroyed, this
413 function will return a null pointer.
414
415 This function can be used, for example, to store the pointer to the
416 contents of the global static in a local variable, thus avoiding multiple
417 calls to the function. The implementation of Q_GLOBAL_STATIC() is quite
418 efficient already, but in performance-critical sections it might be useful
419 to help the compiler a little. For example:
420
421 \code
422 Q_GLOBAL_STATIC(MyType, globalState)
423 QString someState()
424 {
425 MyType *state = globalState;
426 if (!state) {
427 // we're in a post-destruction state
428 return QString();
429 }
430 if (state->condition)
431 return state->value1;
432 else
433 return state->value2;
434 }
435 \endcode
436
437 \sa operator->(), operator*()
438*/
439
440/*!
441 \fn template <typename Holder> Type *QGlobalStatic<Holder>::operator()()
442 \deprecated
443
444 This function returns the address of the contents of this global static. If
445 the contents have not yet been created, they will be created thread-safely
446 by this function. If the contents have already been destroyed, this
447 function will return a null pointer.
448
449 This function is equivalent to \l {qglobalstatic-operator-type-ptr}
450 {operator Type *()}. It is provided for compatibility with the private
451 Q_GLOBAL_STATIC implementation that existed in Qt 4.x and 5.0. New code
452 should avoid using it and should instead treat the object as a smart
453 pointer.
454*/
455
456/*!
457 \fn template <typename Holder> Type *QGlobalStatic<Holder>::operator->()
458
459 This function returns the address of the contents of this global static. If
460 the contents have not yet been created, they will be created thread-safely
461 by this function.
462
463 This function does not check if the contents have already been destroyed and
464 will never return null. If this function is called after the object has
465 been destroyed, it will return a dangling pointer that should not be
466 dereferenced.
467*/
468
469/*!
470 \fn template <typename Holder> Type &QGlobalStatic<Holder>::operator*()
471
472 This function returns a reference to the contents of this global static. If
473 the contents have not yet been created, they will be created thread-safely
474 by this function.
475
476 This function does not check if the contents have already been destroyed.
477 If this function is called after the object has been destroyed, it will
478 return an invalid reference that must not be used.
479*/