source: mainline/abi/include/_bits/macros.h@ 7c3fb9b

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 7c3fb9b was 7c3fb9b, checked in by Jiri Svoboda <jiri@…>, 7 years ago

Fix block comment formatting (ccheck).

  • Property mode set to 100644
File size: 15.3 KB
Line 
1/*
2 * Copyright (c) 2017 CZ.NIC, z.s.p.o.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/*
30 * Authors:
31 * Jiří Zárevúcky (jzr) <zarevucky.jiri@gmail.com>
32 */
33
34/** @addtogroup bits
35 * @{
36 */
37/** @file
38 * Basic macro definitions and redefinitions that support basic C types.
39 *
40 * Both GCC and clang define macros for fixed-size integer names
41 * (e.g. __INT32_TYPE__ for int32_t). However, while clang also provides
42 * definitions for formatting macros (PRId32 et al.), GCC does not.
43 * This poses a subtle problem for diagnostics -- when 'int' and 'long int'
44 * have the same width, it's not possible to detect which one is used to
45 * define 'int32_t', but using a formatting specifier for 'int' on 'long int'
46 * value, or vice versa, causes a compiler warning. Analogous problem occurs
47 * with 'long int' and 'long long int', if they are the same size.
48 *
49 * In the interest of compatibility, we ignore the compiler's opinion on
50 * fixed-size types, and redefine the macros consistently.
51 *
52 * However, we can't do the same for 'size_t', 'ptrdiff_t', 'wchar_t', 'wint_t',
53 * 'intmax_t' and 'uintmax_t', since their format specifiers and other
54 * properties are built into the language and their identity is therefore
55 * determined by the compiler.
56 *
57 * We use some macros if they are present, but provide our own fallbacks when
58 * they are not. There are several macros that have to be predefined either by
59 * the compiler itself, or supplied by the build system if necessary
60 * (e.g. using the '-imacros' compiler argument). This is basically a subset
61 * of the common denominator of GCC and clang predefined macros at this moment.
62 *
63 * These required macros include:
64 *
65 * __CHAR_BIT__
66 * __SIZEOF_SHORT__
67 * __SIZEOF_INT__
68 * __SIZEOF_LONG__
69 * __SIZEOF_LONG_LONG__
70 * __SIZEOF_POINTER__
71 * __SIZEOF_FLOAT__
72 * __SIZEOF_DOUBLE__
73 * __SIZEOF_LONG_DOUBLE__
74 *
75 * __SIZE_TYPE__
76 * __SIZE_MAX__
77 *
78 * __PTRDIFF_TYPE__
79 * __PTRDIFF_MAX__
80 *
81 * __WCHAR_TYPE__
82 * __WCHAR_MAX__
83 *
84 * __WINT_TYPE__
85 * __WINT_MAX__ or
86 * __WINT_WIDTH__ and __WINT_UNSIGNED__ when wint_t is unsigned
87 *
88 * __INTMAX_TYPE__
89 * __INTMAX_MAX__
90 * either __INTMAX_C_SUFFIX__ or __INTMAX_C
91 *
92 * __CHAR_UNSIGNED__ when char is unsigned
93 *
94 * After this header is processed, the following additional macros are
95 * guaranteed to be defined, or the build will fail:
96 *
97 * for {type} being one of CHAR, SHRT, INT, LONG, LLONG
98 * __{type}_MIN__
99 * __{type}_MAX__
100 * __U{type}_MAX__
101 *
102 * __SCHAR_MIN__
103 * __SCHAR_MAX__
104 *
105 * for {size} being one of 8, 16, 32, 64, PTR, MAX
106 * __INT{size}_TYPE__
107 * __INT{size}_MIN__
108 * __INT{size}_MAX__
109 * __UINT{size}_TYPE__
110 * __UINT{size}_MAX__
111 * for {tag} being one of d, i, u, o, x, X
112 * __PRI{tag}{size}__
113 * for {tag} being one of d, i, u, o, x
114 * __SCN{tag}{size}__
115 * __INT{size}_C
116 * __UINT{size}_C
117 * (except for __INTPTR_C/__UINTPTR_C, which aren't provided)
118 *
119 * __PTRDIFF_MIN__
120 * __WCHAR_MIN__
121 * __WINT_MIN__
122 * __WINT_MAX__
123 * __WINT_EOF__
124 * __WCHAR_SIGNED__ or __WCHAR_UNSIGNED__
125 * __WINT_SIGNED__ or __WINT_UNSIGNED__
126 *
127 */
128
129// TODO: add sig_atomic_t for compatibility with C language standard
130
131#ifndef _BITS_MACROS_H_
132#define _BITS_MACROS_H_
133
134#if __CHAR_BIT__ != 8
135#error HelenOS expects char that is 8 bits wide.
136#endif
137
138#ifndef __SCHAR_MAX__
139#define __SCHAR_MAX__ 0x7f
140#endif
141
142#ifndef __SCHAR_MIN__
143#define __SCHAR_MIN__ (-__SCHAR_MAX__ - 1)
144#endif
145
146#ifndef __UCHAR_MAX__
147#define __UCHAR_MAX__ 0xff
148#endif
149
150#ifndef __CHAR_MIN__
151#ifdef __CHAR_UNSIGNED__
152#define __CHAR_MIN__ 0
153#else
154#define __CHAR_MIN__ __SCHAR_MIN__
155#endif
156#endif
157
158#ifndef __CHAR_MAX__
159#ifdef __CHAR_UNSIGNED__
160#define __CHAR_MAX__ __UCHAR_MAX__
161#else
162#define __CHAR_MAX__ __SCHAR_MAX__
163#endif
164#endif
165
166#undef __INT8_TYPE__
167#undef __INT8_C
168#undef __INT8_C_SUFFIX__
169#undef __INT8_MIN__
170#undef __INT8_MAX__
171
172#define __INT8_TYPE__ signed char
173#define __INT8_C(x) x
174#define __INT8_MIN__ __SCHAR_MIN__
175#define __INT8_MAX__ __SCHAR_MAX__
176
177#undef __UINT8_TYPE__
178#undef __UINT8_C
179#undef __UINT8_C_SUFFIX__
180#undef __UINT8_MIN__
181#undef __UINT8_MAX__
182
183#define __UINT8_TYPE__ unsigned char
184#define __UINT8_C(x) x
185#define __UINT8_MAX__ __UCHAR_MAX__
186
187#undef __PRId8__
188#undef __PRIi8__
189#undef __PRIu8__
190#undef __PRIo8__
191#undef __PRIx8__
192#undef __PRIX8__
193
194#define __PRId8__ "hhd"
195#define __PRIi8__ "hhi"
196#define __PRIu8__ "hhu"
197#define __PRIo8__ "hho"
198#define __PRIx8__ "hhx"
199#define __PRIX8__ "hhX"
200
201#undef __SCNd8__
202#undef __SCNi8__
203#undef __SCNu8__
204#undef __SCNo8__
205#undef __SCNx8__
206
207#define __SCNd8__ "hhd"
208#define __SCNi8__ "hhi"
209#define __SCNu8__ "hhu"
210#define __SCNo8__ "hho"
211#define __SCNx8__ "hhx"
212
213#if __SIZEOF_SHORT__ != 2
214#error HelenOS expects short that is 16 bits wide.
215#endif
216
217#ifndef __SHRT_MAX__
218#define __SHRT_MAX__ 0x7fff
219#endif
220
221#ifndef __SHRT_MIN__
222#define __SHRT_MIN__ (-__SHRT_MAX__ - 1)
223#endif
224
225#ifndef __USHRT_MAX__
226#define __USHRT_MAX__ 0xffff
227#endif
228
229#undef __INT16_TYPE__
230#undef __INT16_C
231#undef __INT16_C_SUFFIX__
232#undef __INT16_MIN__
233#undef __INT16_MAX__
234
235#define __INT16_TYPE__ short
236#define __INT16_C(x) x
237#define __INT16_MIN__ __SHRT_MIN__
238#define __INT16_MAX__ __SHRT_MAX__
239
240#undef __UINT16_TYPE__
241#undef __UINT16_C
242#undef __UINT16_C_SUFFIX__
243#undef __UINT16_MIN__
244#undef __UINT16_MAX__
245
246#define __UINT16_TYPE__ unsigned short
247#define __UINT16_C(x) x
248#define __UINT16_MAX__ __USHRT_MAX__
249
250#undef __PRId16__
251#undef __PRIi16__
252#undef __PRIu16__
253#undef __PRIo16__
254#undef __PRIx16__
255#undef __PRIX16__
256
257#define __PRId16__ "hd"
258#define __PRIi16__ "hi"
259#define __PRIu16__ "hu"
260#define __PRIo16__ "ho"
261#define __PRIx16__ "hx"
262#define __PRIX16__ "hX"
263
264#undef __SCNd16__
265#undef __SCNi16__
266#undef __SCNu16__
267#undef __SCNo16__
268#undef __SCNx16__
269
270#define __SCNd16__ "hd"
271#define __SCNi16__ "hi"
272#define __SCNu16__ "hu"
273#define __SCNo16__ "ho"
274#define __SCNx16__ "hx"
275
276#if __SIZEOF_INT__ != 4
277#error HelenOS expects int that is 32 bits wide.
278#endif
279
280#ifndef __INT_MAX__
281#define __INT_MAX__ 0x7fffffff
282#endif
283
284#ifndef __INT_MIN__
285#define __INT_MIN__ (-__INT_MAX__ - 1)
286#endif
287
288#ifndef __UINT_MAX__
289#define __UINT_MAX__ 0xffffffffU
290#endif
291
292#undef __INT32_TYPE__
293#undef __INT32_C
294#undef __INT32_C_SUFFIX__
295#undef __INT32_MIN__
296#undef __INT32_MAX__
297
298#define __INT32_TYPE__ int
299#define __INT32_C(x) x
300#define __INT32_MIN__ __INT_MIN__
301#define __INT32_MAX__ __INT_MAX__
302
303#undef __UINT32_TYPE__
304#undef __UINT32_C
305#undef __UINT32_C_SUFFIX__
306#undef __UINT32_MIN__
307#undef __UINT32_MAX__
308
309#define __UINT32_TYPE__ unsigned int
310#define __UINT32_C(x) x##U
311#define __UINT32_MAX__ __UINT_MAX__
312
313#undef __PRId32__
314#undef __PRIi32__
315#undef __PRIu32__
316#undef __PRIo32__
317#undef __PRIx32__
318#undef __PRIX32__
319
320#define __PRId32__ "d"
321#define __PRIi32__ "i"
322#define __PRIu32__ "u"
323#define __PRIo32__ "o"
324#define __PRIx32__ "x"
325#define __PRIX32__ "X"
326
327#undef __SCNd32__
328#undef __SCNi32__
329#undef __SCNu32__
330#undef __SCNo32__
331#undef __SCNx32__
332
333#define __SCNd32__ "d"
334#define __SCNi32__ "i"
335#define __SCNu32__ "u"
336#define __SCNo32__ "o"
337#define __SCNx32__ "x"
338
339#if __SIZEOF_LONG__ != __SIZEOF_POINTER__
340#error HelenOS expects long that has native width for the architecture.
341#endif
342
343#if __SIZEOF_POINTER__ < 4 || __SIZEOF_POINTER__ > 8
344#error HelenOS expects pointer width to be either 32 bits or 64 bits.
345#endif
346
347#ifndef __LONG_MAX__
348#if __SIZEOF_LONG__ == 4
349#define __LONG_MAX__ 0x7fffffffL
350#elif __SIZEOF_LONG__ == 8
351#define __LONG_MAX__ 0x7fffffffffffffffL
352#endif
353#endif
354
355#ifndef __LONG_MIN__
356#define __LONG_MIN__ (-__LONG_MAX__ - 1)
357#endif
358
359#ifndef __ULONG_MAX__
360#if __SIZEOF_LONG__ == 4
361#define __ULONG_MAX__ 0xffffffffUL
362#elif __SIZEOF_LONG__ == 8
363#define __ULONG_MAX__ 0xffffffffffffffffUL
364#endif
365#endif
366
367#undef __INTPTR_TYPE__
368#undef __INTPTR_C
369#undef __INTPTR_C_SUFFIX__
370#undef __INTPTR_MIN__
371#undef __INTPTR_MAX__
372#undef __UINTPTR_TYPE__
373#undef __UINTPTR_C
374#undef __UINTPTR_C_SUFFIX__
375#undef __UINTPTR_MIN__
376#undef __UINTPTR_MAX__
377#undef __PRIdPTR__
378#undef __PRIiPTR__
379#undef __PRIuPTR__
380#undef __PRIoPTR__
381#undef __PRIxPTR__
382#undef __PRIXPTR__
383#undef __SCNdPTR__
384#undef __SCNiPTR__
385#undef __SCNuPTR__
386#undef __SCNoPTR__
387#undef __SCNxPTR__
388
389#ifdef __intptr_is_long__
390
391#define __INTPTR_TYPE__ long
392#define __INTPTR_MIN__ __LONG_MIN__
393#define __INTPTR_MAX__ __LONG_MAX__
394#define __UINTPTR_TYPE__ unsigned long
395#define __UINTPTR_MAX__ __ULONG_MAX__
396
397#define __PRIdPTR__ "ld"
398#define __PRIiPTR__ "li"
399#define __PRIuPTR__ "lu"
400#define __PRIoPTR__ "lo"
401#define __PRIxPTR__ "lx"
402#define __PRIXPTR__ "lX"
403
404#define __SCNdPTR__ "ld"
405#define __SCNiPTR__ "li"
406#define __SCNuPTR__ "lu"
407#define __SCNoPTR__ "lo"
408#define __SCNxPTR__ "lx"
409
410#else
411
412// Original definition results in size_t and uintptr_t always having the same
413// type. We keep this definition for the time being, to avoid unnecessary noise.
414
415#define __INTPTR_TYPE__ __PTRDIFF_TYPE__
416#define __INTPTR_MIN__ __PTRDIFF_MIN__
417#define __INTPTR_MAX__ __PTRDIFF_MAX__
418#define __UINTPTR_TYPE__ __SIZE_TYPE__
419#define __UINTPTR_MAX__ __SIZE_MAX__
420
421#define __PRIdPTR__ "zd"
422#define __PRIiPTR__ "zi"
423#define __PRIuPTR__ "zu"
424#define __PRIoPTR__ "zo"
425#define __PRIxPTR__ "zx"
426#define __PRIXPTR__ "zX"
427
428#define __SCNdPTR__ "zd"
429#define __SCNiPTR__ "zi"
430#define __SCNuPTR__ "zu"
431#define __SCNoPTR__ "zo"
432#define __SCNxPTR__ "zx"
433
434#endif
435
436#if __SIZEOF_LONG_LONG__ != 8
437#error HelenOS expects long long that is 64 bits wide.
438#endif
439
440#ifndef __LLONG_MAX__
441#define __LLONG_MAX__ 0x7fffffffffffffffLL
442#endif
443
444#ifndef __LLONG_MIN__
445#define __LLONG_MIN__ (-__LLONG_MAX__ - 1)
446#endif
447
448#ifndef __ULLONG_MAX__
449#define __ULLONG_MAX__ 0xffffffffffffffffULL
450#endif
451
452#undef __INT64_TYPE__
453#undef __INT64_C
454#undef __INT64_C_SUFFIX__
455#undef __INT64_MIN__
456#undef __INT64_MAX__
457
458#define __INT64_TYPE__ long long
459#define __INT64_C(x) x##LL
460#define __INT64_MIN__ __LLONG_MIN__
461#define __INT64_MAX__ __LLONG_MAX__
462
463#undef __UINT64_TYPE__
464#undef __UINT64_C
465#undef __UINT64_C_SUFFIX__
466#undef __UINT64_MIN__
467#undef __UINT64_MAX__
468
469#define __UINT64_TYPE__ unsigned long long
470#define __UINT64_C(x) x##ULL
471#define __UINT64_MAX__ __ULLONG_MAX__
472
473#undef __PRId64__
474#undef __PRIi64__
475#undef __PRIu64__
476#undef __PRIo64__
477#undef __PRIx64__
478#undef __PRIX64__
479
480#define __PRId64__ "lld"
481#define __PRIi64__ "lli"
482#define __PRIu64__ "llu"
483#define __PRIo64__ "llo"
484#define __PRIx64__ "llx"
485#define __PRIX64__ "llX"
486
487#undef __SCNd64__
488#undef __SCNi64__
489#undef __SCNu64__
490#undef __SCNo64__
491#undef __SCNx64__
492
493#define __SCNd64__ "lld"
494#define __SCNi64__ "lli"
495#define __SCNu64__ "llu"
496#define __SCNo64__ "llo"
497#define __SCNx64__ "llx"
498
499#if !defined(__SIZE_TYPE__) || !defined(__SIZE_MAX__)
500#error HelenOS expects __SIZE_TYPE__ and __SIZE_MAX__ \
501 to be defined by the toolchain.
502#endif
503
504#if !defined(__PTRDIFF_TYPE__) || !defined(__PTRDIFF_MAX__)
505#error HelenOS expects __PTRDIFF_TYPE__ and __PTRDIFF_MAX__ \
506 to be defined by the toolchain.
507#endif
508
509#ifndef __PTRDIFF_MIN__
510#define __PTRDIFF_MIN__ (-__PTRDIFF_MAX__ - 1)
511#endif
512
513#if !defined(__WCHAR_TYPE__) || !defined(__WCHAR_MAX__)
514#error HelenOS expects __WCHAR_TYPE__ and __WCHAR_MAX__ \
515 to be defined by the toolchain.
516#endif
517
518#undef __WCHAR_SIGNED__
519#undef __WCHAR_UNSIGNED__
520
521#if __WCHAR_MAX__ == __INT32_MAX__
522#define __WCHAR_SIGNED__ 1
523#elif __WCHAR_MAX__ == __UINT32_MAX__
524#define __WCHAR_UNSIGNED__ 1
525#else
526#error HelenOS expects __WCHAR_TYPE__ to be 32 bits wide.
527#endif
528
529#ifndef __WCHAR_MIN__
530#ifdef __WCHAR_UNSIGNED__
531#define __WCHAR_MIN__ 0
532#else
533#define __WCHAR_MIN__ (-__WCHAR_MAX__ - 1)
534#endif
535#endif
536
537#if !defined(__WINT_TYPE__) || !defined(__WINT_WIDTH__)
538#error HelenOS expects __WINT_TYPE__ and __WINT_WIDTH__ \
539 to be defined by the toolchain.
540#endif
541
542#if __WINT_WIDTH__ != 32
543#error HelenOS expects __WINT_TYPE__ to be 32 bits wide.
544#endif
545
546#undef __WINT_SIGNED__
547#undef __WINT_UNSIGNED__
548
549#if __WINT_MAX__ == __INT32_MAX__
550#define __WINT_SIGNED__ 1
551#elif __WINT_MAX__ == __UINT32_MAX__
552#define __WINT_UNSIGNED__ 1
553#elif defined(__WINT_MAX__)
554#error Unrecognized value of __WINT_MAX__
555#endif
556
557#ifndef __WINT_MAX__
558#ifdef __WINT_UNSIGNED__
559#define __WINT_MAX__ 0xffffffffU
560#else
561#define __WINT_MAX__ 0x7fffffff
562#endif
563#endif
564
565#ifndef __WINT_MIN__
566#ifdef __WINT_UNSIGNED__
567#define __WINT_MIN__ 0
568#else
569#define __WINT_MIN__ (-__WINT_MAX__ - 1)
570#endif
571#endif
572
573#ifndef __WINT_EOF__
574#ifdef __WINT_UNSIGNED__
575#define __WINT_EOF__ __WINT_MAX__
576#else
577#define __WINT_EOF__ -1
578#endif
579#endif
580
581#ifndef __HELENOS_DISABLE_INTMAX__
582
583#if !defined(__INTMAX_TYPE__) || !defined(__INTMAX_MAX__)
584#error HelenOS expects __INTMAX_TYPE__ and __INTMAX_MAX__ \
585 to be defined by the toolchain.
586#endif
587
588#ifndef __INTMAX_MIN__
589#define __INTMAX_MIN__ (-__INTMAX_MAX__ - 1)
590#endif
591
592#ifndef __INTMAX_C
593#ifndef __INTMAX_C_SUFFIX__
594#error HelenOS expects __INTMAX_C or __INTMAX_C_SUFFIX__ \
595 to be defined by the toolchain.
596#endif
597#define __INTMAX_C__(x, y) x##y
598#define __INTMAX_C(x) __INTMAX_C__(x, __INTMAX_C_SUFFIX__)
599#endif
600
601#ifndef __UINTMAX_TYPE__
602#define __UINTMAX_TYPE__ unsigned __INTMAX_TYPE__
603#endif
604
605#ifndef __UINTMAX_C
606#ifdef __UINTMAX_C_SUFFIX__
607#define __UINTMAX_C__(x, y) x##y
608#define __UINTMAX_C(x) __UINTMAX_C__(x, __UINTMAX_C_SUFFIX__)
609#else
610#define __UINTMAX_C(x) __INTMAX_C(x##U)
611#endif
612#endif
613
614#ifndef __UINTMAX_MAX__
615#define ___UNSIGNED_INTMAX_MAX___(x) x##U
616#define __UINTMAX_MAX__ (2 * ___UNSIGNED_INTMAX_MAX___(__INTMAX_MAX__) + 1)
617#endif
618
619#undef __PRIdMAX__
620#undef __PRIiMAX__
621#undef __PRIuMAX__
622#undef __PRIoMAX__
623#undef __PRIxMAX__
624#undef __PRIXMAX__
625
626#define __PRIdMAX__ "jd"
627#define __PRIiMAX__ "ji"
628#define __PRIuMAX__ "ju"
629#define __PRIoMAX__ "jo"
630#define __PRIxMAX__ "jx"
631#define __PRIXMAX__ "jX"
632
633#undef __SCNdMAX__
634#undef __SCNiMAX__
635#undef __SCNuMAX__
636#undef __SCNoMAX__
637#undef __SCNxMAX__
638
639#define __SCNdMAX__ "jd"
640#define __SCNiMAX__ "ji"
641#define __SCNuMAX__ "ju"
642#define __SCNoMAX__ "jo"
643#define __SCNxMAX__ "jx"
644
645#endif /* __HELENOS_DISABLE_INTMAX__ */
646
647#ifndef __SIZEOF_FLOAT__
648#error HelenOS expects __SIZEOF_FLOAT__ to be defined.
649#endif
650
651#ifndef __SIZEOF_DOUBLE__
652#error HelenOS expects __SIZEOF_DOUBLE__ to be defined.
653#endif
654
655#ifndef __SIZEOF_LONG_DOUBLE__
656#error HelenOS expects __SIZEOF_LONG_DOUBLE__ to be defined.
657#endif
658
659#endif
660
661/** @}
662 */
Note: See TracBrowser for help on using the repository browser.