C++学习------cstdint头文件的源码学习02

379 阅读5分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第17天,点击查看活动详情

# C++学习------cstdint头文件的源码学习01

续接上文讲解

常见整型的上下限

这里事先定义了如下整形的上下限

占用位数有符号/无符号上限下限
8有符号127-128
8无符号2550
16有符号32767-32768
16无符号655350
32有符号2147483647-2147483647-1
32无符号4294967295U0
64有符号INT64_C(9223372036854775807)INT64_C(-9223372036854775807)-1
64无符号UINT64_C(18446744073709551615)0

注意:这里用到了一些宏定义,我们在后面一节里面会说明它的含义

154  #define INT8_MIN         (-128)
155  #define INT8_MAX         (127)
156  #define INT_LEAST8_MIN   INT8_MIN
157  #define INT_LEAST8_MAX   INT8_MAX
158  #define INT_FAST8_MIN    INT8_MIN
159  #define INT_FAST8_MAX    INT8_MAX
160  
161  #define UINT8_MAX        (255)
162  #define UINT_LEAST8_MAX  UINT8_MAX
163  #define UINT_FAST8_MAX   UINT8_MAX
164  
165  #define INT16_MIN        (-32768)
166  #define INT16_MAX        (32767)
167  #define INT_LEAST16_MIN  INT16_MIN
168  #define INT_LEAST16_MAX  INT16_MAX
169  #define INT_FAST16_MIN   INT32_MIN
170  #define INT_FAST16_MAX   INT32_MAX
171  
172  #define UINT16_MAX       (65535)
173  #define UINT_LEAST16_MAX UINT16_MAX
174  #define UINT_FAST16_MAX  UINT32_MAX
175  
176  #define INT32_MIN        (-2147483647-1)
177  #define INT32_MAX        (2147483647)
178  #define INT_LEAST32_MIN  INT32_MIN
179  #define INT_LEAST32_MAX  INT32_MAX
180  #define INT_FAST32_MIN   INT32_MIN
181  #define INT_FAST32_MAX   INT32_MAX
182  
183  #define UINT32_MAX       (4294967295U)
184  #define UINT_LEAST32_MAX UINT32_MAX
185  #define UINT_FAST32_MAX  UINT32_MAX
186  
187  #define INT64_MIN        (INT64_C(-9223372036854775807)-1)
188  #define INT64_MAX        (INT64_C(9223372036854775807))
189  #define INT_LEAST64_MIN  INT64_MIN
190  #define INT_LEAST64_MAX  INT64_MAX
191  #define INT_FAST64_MIN   INT64_MIN
192  #define INT_FAST64_MAX   INT64_MAX
193  #define UINT64_MAX       (UINT64_C(18446744073709551615))
194  
195  #define UINT_LEAST64_MAX UINT64_MAX
196  #define UINT_FAST64_MAX  UINT64_MAX
197  
198  #define INTMAX_MIN       INT64_MIN
199  #define INTMAX_MAX       INT64_MAX
200  #define UINTMAX_MAX      UINT64_MAX
201  
202  #define SIG_ATOMIC_MAX   INT32_MAX
203  #define SIG_ATOMIC_MIN   INT32_MIN
204  
205  #if defined(__WINT_UNSIGNED__)
206  #  define WINT_MAX       UINT32_MAX
207  #  define WINT_MIN       0
208  #else
209  #  define WINT_MAX       INT32_MAX
210  #  define WINT_MIN       INT32_MIN
211  #endif
212  
213  #if defined(__LP64__)
214  #  define INTPTR_MIN     INT64_MIN
215  #  define INTPTR_MAX     INT64_MAX
216  #  define UINTPTR_MAX    UINT64_MAX
217  #  define PTRDIFF_MIN    INT64_MIN
218  #  define PTRDIFF_MAX    INT64_MAX
219  #  define SIZE_MAX       UINT64_MAX
220  #else
221  #  define INTPTR_MIN     INT32_MIN
222  #  define INTPTR_MAX     INT32_MAX
223  #  define UINTPTR_MAX    UINT32_MAX
224  #  define PTRDIFF_MIN    INT32_MIN
225  #  define PTRDIFF_MAX    INT32_MAX
226  #  define SIZE_MAX       UINT32_MAX
227  #endif

与之前不同,这里的fast值和least值的max和min定义大部分与对应的基础值一样,不一样的是:

#define INT_FAST16_MIN   INT32_MIN
#define INT_FAST16_MAX   INT32_MAX

定义为INT32_MIN和INT32_MAX 同时,其它的一些size,如SIG_ATOMIC_MAX(原子量),WINT_MAX(根据是否有符号进行区分),PTRDIFF_MAX(指针运算差值)SIZE_MAX(size_t的取值)

类型转换宏

实际上是运用了字面值常量的前后缀来生成宏:

  • u或U,最小匹配unsigned
  • l或L,最小匹配long
  • ll或LL,最小匹配long long
106  /* Keep the kernel from trying to define these types... */
107  #define __BIT_TYPES_DEFINED__
108  
109  #define INT8_C(c)         c
110  #define INT_LEAST8_C(c)   INT8_C(c)
111  #define INT_FAST8_C(c)    INT8_C(c)
112  
113  #define UINT8_C(c)        c
114  #define UINT_LEAST8_C(c)  UINT8_C(c)
115  #define UINT_FAST8_C(c)   UINT8_C(c)
116  
117  #define INT16_C(c)        c
118  #define INT_LEAST16_C(c)  INT16_C(c)
119  #define INT_FAST16_C(c)   INT32_C(c)
120  
121  #define UINT16_C(c)       c
122  #define UINT_LEAST16_C(c) UINT16_C(c)
123  #define UINT_FAST16_C(c)  UINT32_C(c)
124  #define INT32_C(c)        c
125  #define INT_LEAST32_C(c)  INT32_C(c)
126  #define INT_FAST32_C(c)   INT32_C(c)
127  
128  #define UINT32_C(c)       c ## U
129  #define UINT_LEAST32_C(c) UINT32_C(c)
130  #define UINT_FAST32_C(c)  UINT32_C(c)
131  #define INT_LEAST64_C(c)  INT64_C(c)
132  #define INT_FAST64_C(c)   INT64_C(c)
133  
134  #define UINT_LEAST64_C(c) UINT64_C(c)
135  #define UINT_FAST64_C(c)  UINT64_C(c)
136  
137  #define INTMAX_C(c)       INT64_C(c)
138  #define UINTMAX_C(c)      UINT64_C(c)
139  
140  #if defined(__LP64__)
141  #  define INT64_C(c)      c ## L
142  #  define UINT64_C(c)     c ## UL
143  #  define INTPTR_C(c)     INT64_C(c)
144  #  define UINTPTR_C(c)    UINT64_C(c)
145  #  define PTRDIFF_C(c)    INT64_C(c)
146  #else
147  #  define INT64_C(c)      c ## LL
148  #  define UINT64_C(c)     c ## ULL
149  #  define INTPTR_C(c)     INT32_C(c)
150  #  define UINTPTR_C(c)    UINT32_C(c)
151  #  define PTRDIFF_C(c)    INT32_C(c)
152  #endif

所以,上面的匹配中,针对32位机器的无符号64位表示为: # define UINT64_C(c) c ## ULL

"##"在宏定义中代表将前后以字符相连,即一个数字将表示为cULL,即该字面值为unsigned long long类型

回到之前我们定义上下限的位置,UINT64_C(18446744073709551615)在编译时就被表示为18446744073709551615ULL。

总结

stdint.h头文件中定义是为了兼容32位和64位机器,保证使用对应的定义能够获取对应位数的变量,平时我们在编程时,也需要多加考虑程序在多个平台之间的可移植性,尽量使用与平台无关的变量定义,如使用int32_t代替int。