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
*/
qtbase
src
corelib
global
qglobalstatic.qdoc
Generated on
for Qt by
1.14.0