source: mainline/abi/include/_bits/macros.h@ 66855b2

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 66855b2 was e9690b6, checked in by jzr <zarevucky.jiri@…>, 8 years ago

Allow disabling intmax_t in downstream code (used in coastline).

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