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