1 | // Copyright (C) 2022 The Qt Company Ltd. |
2 | // Copyright (C) 2022 Intel Corporation. |
3 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
4 | |
5 | #include "qtypes.h" |
6 | |
7 | #include <QtCore/qcompilerdetection.h> |
8 | #include <QtCore/qsystemdetection.h> |
9 | #include <QtCore/qprocessordetection.h> |
10 | |
11 | #include <climits> |
12 | #include <limits> |
13 | #include <type_traits> |
14 | |
15 | QT_BEGIN_NAMESPACE |
16 | |
17 | /*! |
18 | \headerfile <QtTypes> |
19 | \inmodule QtCore |
20 | \title Qt Type Declarations |
21 | |
22 | \brief The <QtTypes> header file includes Qt fundamental type declarations. |
23 | |
24 | The header file declares several type definitions that guarantee a |
25 | specified bit-size on all platforms supported by Qt for various |
26 | basic types, for example \l qint8 which is a signed char |
27 | guaranteed to be 8-bit on all platforms supported by Qt. The |
28 | header file also declares the \l qlonglong type definition for |
29 | \c {long long int}. |
30 | |
31 | Several convenience type definitions are declared: \l qreal for \c |
32 | double or \c float, \l uchar for \c {unsigned char}, \l uint for |
33 | \c {unsigned int}, \l ulong for \c {unsigned long} and \l ushort |
34 | for \c {unsigned short}. |
35 | |
36 | The header also provides series of macros that make it possible to print |
37 | some Qt type aliases (qsizetype, qintptr, etc.) via a formatted output |
38 | facility such as printf() or qDebug() without raising formatting warnings |
39 | and without the need of a type cast. |
40 | */ |
41 | |
42 | /*! |
43 | \typedef qreal |
44 | \relates <QtTypes> |
45 | |
46 | Typedef for \c double unless Qt is configured with the |
47 | \c{-qreal float} option. |
48 | */ |
49 | |
50 | /*! \typedef uchar |
51 | \relates <QtTypes> |
52 | |
53 | Convenience typedef for \c{unsigned char}. |
54 | */ |
55 | |
56 | /*! \typedef ushort |
57 | \relates <QtTypes> |
58 | |
59 | Convenience typedef for \c{unsigned short}. |
60 | */ |
61 | |
62 | /*! \typedef uint |
63 | \relates <QtTypes> |
64 | |
65 | Convenience typedef for \c{unsigned int}. |
66 | */ |
67 | |
68 | /*! \typedef ulong |
69 | \relates <QtTypes> |
70 | |
71 | Convenience typedef for \c{unsigned long}. |
72 | */ |
73 | |
74 | /*! \typedef qint8 |
75 | \relates <QtTypes> |
76 | |
77 | Typedef for \c{signed char}. This type is guaranteed to be 8-bit |
78 | on all platforms supported by Qt. |
79 | */ |
80 | |
81 | /*! |
82 | \typedef quint8 |
83 | \relates <QtTypes> |
84 | |
85 | Typedef for \c{unsigned char}. This type is guaranteed to |
86 | be 8-bit on all platforms supported by Qt. |
87 | */ |
88 | |
89 | /*! \typedef qint16 |
90 | \relates <QtTypes> |
91 | |
92 | Typedef for \c{signed short}. This type is guaranteed to be |
93 | 16-bit on all platforms supported by Qt. |
94 | */ |
95 | |
96 | /*! |
97 | \typedef quint16 |
98 | \relates <QtTypes> |
99 | |
100 | Typedef for \c{unsigned short}. This type is guaranteed to |
101 | be 16-bit on all platforms supported by Qt. |
102 | */ |
103 | |
104 | /*! \typedef qint32 |
105 | \relates <QtTypes> |
106 | |
107 | Typedef for \c{signed int}. This type is guaranteed to be 32-bit |
108 | on all platforms supported by Qt. |
109 | */ |
110 | |
111 | /*! |
112 | \typedef quint32 |
113 | \relates <QtTypes> |
114 | |
115 | Typedef for \c{unsigned int}. This type is guaranteed to |
116 | be 32-bit on all platforms supported by Qt. |
117 | */ |
118 | |
119 | /*! \typedef qint64 |
120 | \relates <QtTypes> |
121 | |
122 | Typedef for \c{long long int}. This type is guaranteed to be 64-bit |
123 | on all platforms supported by Qt. |
124 | |
125 | Literals of this type can be created using the Q_INT64_C() macro: |
126 | |
127 | \snippet code/src_corelib_global_qglobal.cpp 5 |
128 | |
129 | \sa Q_INT64_C(), quint64, qlonglong |
130 | */ |
131 | |
132 | /*! |
133 | \typedef quint64 |
134 | \relates <QtTypes> |
135 | |
136 | Typedef for \c{unsigned long long int}. This type is guaranteed to |
137 | be 64-bit on all platforms supported by Qt. |
138 | |
139 | Literals of this type can be created using the Q_UINT64_C() |
140 | macro: |
141 | |
142 | \snippet code/src_corelib_global_qglobal.cpp 6 |
143 | |
144 | \sa Q_UINT64_C(), qint64, qulonglong |
145 | */ |
146 | |
147 | /*! |
148 | \typedef qint128 |
149 | \relates <QtTypes> |
150 | \since 6.6 |
151 | |
152 | Typedef for \c{__int128} on platforms that support it (Qt defines the macro |
153 | \l QT_SUPPORTS_INT128 if this is the case). |
154 | |
155 | Literals of this type can be created using the Q_INT128_C() macro. |
156 | |
157 | \sa Q_INT128_C(), Q_INT128_MIN, Q_INT128_MAX, quint128, QT_SUPPORTS_INT128 |
158 | */ |
159 | |
160 | /*! |
161 | \typedef quint128 |
162 | \relates <QtTypes> |
163 | \since 6.6 |
164 | |
165 | Typedef for \c{unsigned __int128} on platforms that support it (Qt defines |
166 | the macro \l QT_SUPPORTS_INT128 if this is the case). |
167 | |
168 | Literals of this type can be created using the Q_UINT128_C() macro. |
169 | |
170 | \sa Q_UINT128_C(), Q_UINT128_MAX, qint128, QT_SUPPORTS_INT128 |
171 | */ |
172 | |
173 | /*! |
174 | \macro QT_SUPPORTS_INT128 |
175 | \relates <QtTypes> |
176 | \since 6.6 |
177 | |
178 | Qt defines this macro as well as the \l qint128 and \l quint128 types if |
179 | the platform has support for 128-bit integer types. |
180 | |
181 | \sa qint128, quint128, Q_INT128_C(), Q_UINT128_C(), Q_INT128_MIN, Q_INT128_MAX, Q_UINT128_MAX |
182 | */ |
183 | |
184 | /*! |
185 | \typedef qintptr |
186 | \relates <QtTypes> |
187 | |
188 | Integral type for representing pointers in a signed integer (useful for |
189 | hashing, etc.). |
190 | |
191 | Typedef for either qint32 or qint64. This type is guaranteed to |
192 | be the same size as a pointer on all platforms supported by Qt. On |
193 | a system with 32-bit pointers, qintptr is a typedef for qint32; |
194 | on a system with 64-bit pointers, qintptr is a typedef for |
195 | qint64. |
196 | |
197 | Note that qintptr is signed. Use quintptr for unsigned values. |
198 | |
199 | In order to print values of this type by using formatted-output |
200 | facilities such as \c{printf()}, qDebug(), QString::asprintf() and |
201 | so on, you can use the \c{PRIdQINTPTR} and \c{PRIiQINTPTR} |
202 | macros as format specifiers. They will both print the value as a |
203 | base 10 number. |
204 | |
205 | \code |
206 | qintptr p = 123; |
207 | printf("The pointer is %" PRIdQINTPTR "\n", p); |
208 | \endcode |
209 | |
210 | \sa qptrdiff, qint32, qint64 |
211 | */ |
212 | |
213 | /*! \typedef qlonglong |
214 | \relates <QtTypes> |
215 | |
216 | Typedef for \c{long long int} (\c __int64 on Windows). This is |
217 | the same as \l qint64. |
218 | |
219 | \sa qulonglong, qint64 |
220 | */ |
221 | |
222 | /*! |
223 | \typedef qulonglong |
224 | \relates <QtTypes> |
225 | |
226 | Typedef for \c{unsigned long long int} (\c{unsigned __int64} on |
227 | Windows). This is the same as \l quint64. |
228 | |
229 | \sa quint64, qlonglong |
230 | */ |
231 | |
232 | /*! |
233 | \macro PRIdQINTPTR |
234 | \macro PRIiQINTPTR |
235 | \since 6.2 |
236 | \relates <QtTypes> |
237 | |
238 | See \l qintptr. |
239 | */ |
240 | |
241 | /*! |
242 | \typedef quintptr |
243 | \relates <QtTypes> |
244 | |
245 | Integral type for representing pointers in an unsigned integer (useful for |
246 | hashing, etc.). |
247 | |
248 | Typedef for either quint32 or quint64. This type is guaranteed to |
249 | be the same size as a pointer on all platforms supported by Qt. On |
250 | a system with 32-bit pointers, quintptr is a typedef for quint32; |
251 | on a system with 64-bit pointers, quintptr is a typedef for |
252 | quint64. |
253 | |
254 | Note that quintptr is unsigned. Use qptrdiff for signed values. |
255 | |
256 | In order to print values of this type by using formatted-output |
257 | facilities such as \c{printf()}, qDebug(), QString::asprintf() and |
258 | so on, you can use the following macros as format specifiers: |
259 | |
260 | \list |
261 | \li \c{PRIuQUINTPTR}: prints the value as a base 10 number. |
262 | \li \c{PRIoQUINTPTR}: prints the value as a base 8 number. |
263 | \li \c{PRIxQUINTPTR}: prints the value as a base 16 number, using lowercase \c{a-f} letters. |
264 | \li \c{PRIXQUINTPTR}: prints the value as a base 16 number, using uppercase \c{A-F} letters. |
265 | \endlist |
266 | |
267 | \code |
268 | quintptr p = 123u; |
269 | printf("The pointer value is 0x%" PRIXQUINTPTR "\n", p); |
270 | \endcode |
271 | |
272 | \sa qptrdiff, quint32, quint64 |
273 | */ |
274 | |
275 | /*! |
276 | \macro PRIoQUINTPTR |
277 | \macro PRIuQUINTPTR |
278 | \macro PRIxQUINTPTR |
279 | \macro PRIXQUINTPTR |
280 | \since 6.2 |
281 | \relates <QtTypes> |
282 | |
283 | See quintptr. |
284 | */ |
285 | |
286 | /*! |
287 | \typedef qptrdiff |
288 | \relates <QtTypes> |
289 | |
290 | Integral type for representing pointer differences. |
291 | |
292 | Typedef for either qint32 or qint64. This type is guaranteed to be |
293 | the same size as a pointer on all platforms supported by Qt. On a |
294 | system with 32-bit pointers, quintptr is a typedef for quint32; on |
295 | a system with 64-bit pointers, quintptr is a typedef for quint64. |
296 | |
297 | Note that qptrdiff is signed. Use quintptr for unsigned values. |
298 | |
299 | In order to print values of this type by using formatted-output |
300 | facilities such as \c{printf()}, qDebug(), QString::asprintf() and |
301 | so on, you can use the \c{PRIdQPTRDIFF} and \c{PRIiQPTRDIFF} |
302 | macros as format specifiers. They will both print the value as a |
303 | base 10 number. |
304 | |
305 | \code |
306 | qptrdiff d = 123; |
307 | printf("The difference is %" PRIdQPTRDIFF "\n", d); |
308 | \endcode |
309 | |
310 | \sa quintptr, qint32, qint64 |
311 | */ |
312 | |
313 | /*! |
314 | \macro PRIdQPTRDIFF |
315 | \macro PRIiQPTRDIFF |
316 | \since 6.2 |
317 | \relates <QtTypes> |
318 | |
319 | See qptrdiff. |
320 | */ |
321 | |
322 | /*! |
323 | \typedef qsizetype |
324 | \relates <QtTypes> |
325 | \since 5.10 |
326 | |
327 | Integral type providing Posix' \c ssize_t for all platforms. |
328 | |
329 | This type is guaranteed to be the same size as a \c size_t on all |
330 | platforms supported by Qt. |
331 | |
332 | Note that qsizetype is signed. Use \c size_t for unsigned values. |
333 | |
334 | In order to print values of this type by using formatted-output |
335 | facilities such as \c{printf()}, qDebug(), QString::asprintf() and |
336 | so on, you can use the \c{PRIdQSIZETYPE} and \c{PRIiQSIZETYPE} |
337 | macros as format specifiers. They will both print the value as a |
338 | base 10 number. |
339 | |
340 | \code |
341 | qsizetype s = 123; |
342 | printf("The size is %" PRIdQSIZETYPE "\n", s); |
343 | \endcode |
344 | |
345 | \sa qptrdiff |
346 | */ |
347 | |
348 | /*! |
349 | \macro PRIdQSIZETYPE |
350 | \macro PRIiQSIZETYPE |
351 | \since 6.2 |
352 | \relates <QtTypes> |
353 | |
354 | See qsizetype. |
355 | */ |
356 | |
357 | /*! \macro qint64 Q_INT64_C(literal) |
358 | \relates <QtTypes> |
359 | |
360 | Wraps the signed 64-bit integer \a literal in a |
361 | platform-independent way. |
362 | |
363 | Example: |
364 | |
365 | \snippet code/src_corelib_global_qglobal.cpp 8 |
366 | |
367 | \sa qint64, Q_UINT64_C(), Q_INT128_C() |
368 | */ |
369 | |
370 | /*! \macro quint64 Q_UINT64_C(literal) |
371 | \relates <QtTypes> |
372 | |
373 | Wraps the unsigned 64-bit integer \a literal in a |
374 | platform-independent way. |
375 | |
376 | Example: |
377 | |
378 | \snippet code/src_corelib_global_qglobal.cpp 9 |
379 | |
380 | \sa quint64, Q_INT64_C(), Q_UINT128_C() |
381 | */ |
382 | |
383 | /*! |
384 | \macro qint128 Q_INT128_C(literal) |
385 | \relates <QtTypes> |
386 | \since 6.6 |
387 | |
388 | Wraps the signed 128-bit integer \a literal in a |
389 | platform-independent way. |
390 | |
391 | \note Unlike Q_INT64_C(), this macro is only available in C++, not in C. |
392 | This is because compilers do not provide these literals as built-ins and C |
393 | does not have support for user-defined literals. |
394 | |
395 | \sa qint128, Q_UINT128_C(), Q_INT128_MIN, Q_INT128_MAX, Q_INT64_C(), QT_SUPPORTS_INT128 |
396 | */ |
397 | |
398 | /*! |
399 | \macro quint128 Q_UINT128_C(literal) |
400 | \relates <QtTypes> |
401 | \since 6.6 |
402 | |
403 | Wraps the unsigned 128-bit integer \a literal in a |
404 | platform-independent way. |
405 | |
406 | \note Unlike Q_UINT64_C(), this macro is only available in C++, not in C. |
407 | This is because compilers do not provide these literals as built-ins and C |
408 | does not have support for user-defined literals. |
409 | |
410 | \sa quint128, Q_INT128_C(), Q_UINT128_MAX, Q_UINT64_C(), QT_SUPPORTS_INT128 |
411 | */ |
412 | |
413 | /*! |
414 | \macro Q_UINT128_MAX |
415 | \relates <QtTypes> |
416 | \since 6.6 |
417 | |
418 | This macro expands to a compile-time constant representing the |
419 | maximum value representable in a \l quint128. |
420 | |
421 | This macro is available in both C++ and C modes. |
422 | |
423 | The minimum of \l quint128 is 0 (zero), so a \c{Q_UINT128_MIN} is neither |
424 | needed nor provided. |
425 | |
426 | \sa Q_INT128_MAX, quint128, Q_UINT128_C, QT_SUPPORTS_INT128 |
427 | */ |
428 | |
429 | /*! |
430 | \macro Q_INT128_MIN |
431 | \relates <QtTypes> |
432 | \since 6.6 |
433 | |
434 | This macro expands to a compile-time constant representing the |
435 | minimum value representable in a \l qint128. |
436 | |
437 | This macro is available in both C++ and C modes. |
438 | |
439 | \sa Q_INT128_MAX, qint128, Q_INT128_C, QT_SUPPORTS_INT128 |
440 | */ |
441 | |
442 | /*! |
443 | \macro Q_INT128_MAX |
444 | \relates <QtTypes> |
445 | \since 6.6 |
446 | |
447 | This macro expands to a compile-time constant representing the |
448 | maximum value representable in a \l qint128. |
449 | |
450 | This macro is available in both C++ and C modes. |
451 | |
452 | \sa Q_INT128_MIN, Q_UINT128_MAX, qint128, Q_INT128_C, QT_SUPPORTS_INT128 |
453 | */ |
454 | |
455 | // Statically check assumptions about the environment we're running |
456 | // in. The idea here is to error or warn if otherwise implicit Qt |
457 | // assumptions are not fulfilled on new hardware or compilers |
458 | // (if this list becomes too long, consider factoring into a separate file) |
459 | static_assert(UCHAR_MAX == 255, "Qt assumes that char is 8 bits" ); |
460 | static_assert(sizeof(int) == 4, "Qt assumes that int is 32 bits" ); |
461 | static_assert(QT_POINTER_SIZE == sizeof(void *), "QT_POINTER_SIZE defined incorrectly" ); |
462 | static_assert(sizeof(float) == 4, "Qt assumes that float is 32 bits" ); |
463 | static_assert(sizeof(char16_t) == 2, "Qt assumes that char16_t is 16 bits" ); |
464 | static_assert(sizeof(char32_t) == 4, "Qt assumes that char32_t is 32 bits" ); |
465 | #if defined(Q_OS_WIN) |
466 | static_assert(sizeof(wchar_t) == sizeof(char16_t)); |
467 | #endif |
468 | static_assert(std::numeric_limits<int>::radix == 2, |
469 | "Qt assumes binary integers" ); |
470 | static_assert((std::numeric_limits<int>::max() + std::numeric_limits<int>::lowest()) == -1, |
471 | "Qt assumes two's complement integers" ); |
472 | static_assert(sizeof(wchar_t) == sizeof(char32_t) || sizeof(wchar_t) == sizeof(char16_t), |
473 | "Qt assumes wchar_t is compatible with either char32_t or char16_t" ); |
474 | |
475 | // While we'd like to check for __STDC_IEC_559__, as per ISO/IEC 9899:2011 |
476 | // Annex F (C11, normative for C++11), there are a few corner cases regarding |
477 | // denormals where GHS compiler is relying hardware behavior that is not IEC |
478 | // 559 compliant. So split the check in several subchecks. |
479 | |
480 | // On GHS the compiler reports std::numeric_limits<float>::is_iec559 as false. |
481 | // This is all right according to our needs. |
482 | #if !defined(Q_CC_GHS) |
483 | static_assert(std::numeric_limits<float>::is_iec559, |
484 | "Qt assumes IEEE 754 floating point" ); |
485 | #endif |
486 | |
487 | // Technically, presence of NaN and infinities are implied from the above check, |
488 | // but double checking our environment doesn't hurt... |
489 | static_assert(std::numeric_limits<float>::has_infinity && |
490 | std::numeric_limits<float>::has_quiet_NaN, |
491 | "Qt assumes IEEE 754 floating point" ); |
492 | |
493 | // is_iec559 checks for ISO/IEC/IEEE 60559:2011 (aka IEEE 754-2008) compliance, |
494 | // but that allows for a non-binary radix. We need to recheck that. |
495 | // Note how __STDC_IEC_559__ would instead check for IEC 60559:1989, aka |
496 | // ANSI/IEEE 754−1985, which specifically implies binary floating point numbers. |
497 | static_assert(std::numeric_limits<float>::radix == 2, |
498 | "Qt assumes binary IEEE 754 floating point" ); |
499 | |
500 | // not required by the definition of size_t, but we depend on this |
501 | static_assert(sizeof(size_t) == sizeof(void *), "size_t and a pointer don't have the same size" ); |
502 | static_assert(sizeof(size_t) == sizeof(qsizetype)); // implied by the definition |
503 | static_assert((std::is_same<qsizetype, qptrdiff>::value)); |
504 | static_assert(std::is_same_v<std::size_t, size_t>); |
505 | |
506 | // Check that our own typedefs are not broken. |
507 | static_assert(sizeof(qint8) == 1, "Internal error, qint8 is misdefined" ); |
508 | static_assert(sizeof(qint16)== 2, "Internal error, qint16 is misdefined" ); |
509 | static_assert(sizeof(qint32) == 4, "Internal error, qint32 is misdefined" ); |
510 | static_assert(sizeof(qint64) == 8, "Internal error, qint64 is misdefined" ); |
511 | #ifdef QT_SUPPORTS_INT128 |
512 | static_assert(sizeof(qint128) == 16, "Internal error, qint128 is misdefined" ); |
513 | #endif |
514 | |
515 | #ifdef QT_SUPPORTS_INT128 |
516 | // check that numeric_limits works: |
517 | // This fails here for GCC 9, but succeeds on Clang and GCC >= 11 |
518 | // However, all tests in tst_qglobal::int128Literals() pass for GCC 9, too, |
519 | // so just suppress the check for older GCC: |
520 | # if !defined(Q_CC_GNU_ONLY) || Q_CC_GNU >= 1100 |
521 | static_assert(std::numeric_limits<quint128>::max() == Q_UINT128_MAX); |
522 | # endif |
523 | #endif |
524 | |
525 | QT_END_NAMESPACE |
526 | |