认识 `<stdint.h>` (一)

<stdint.h>是C99的标准,在里面定义了8,16,32,64位的有符号和无符号整数类型定义。 分别是:

  • int8_t, int16_t, int32_t, int64_t;
  • uint8_t, uint16_t, uint32_t, uint64_t;

那么,这些类型具体是什么呢?让我们一起追下源代码。我们看下 glibc2.38 的源代码。glibc 最新版本是2.38,正在开发中的是2.39,2.40,每6个月一个版本,这个项目从1988开始已经35年了,所有的版本一共144个版本。

https://sourceware.org/glibc/wiki/Glibc Timeline

可以在线查看glibc的源代码:https://sourceware.org/git/?p=glibc.git;a=summary

不过我们可以看另外一个更适合查看的地址:https://elixir.bootlin.com/glibc/latest/source

通过层层追踪,可以看到 stdint.h里 对这几个整型的定义

0)查看 stdlib/stdint.h
在线查看: https://elixir.bootlin.com/glibc/latest/source/stdlib/stdint.h

可以看到里面依赖

<bits/stdint-intn.h>
<bits/stdint-uintn.h>

a)进一步查看:bits/stdint-intn.h
在线查看: https://elixir.bootlin.com/glibc/latest/source/bits/stdint-intn.h

可以看到

typedef __int8_t int8_t;
typedef __int16_t int16_t;
typedef __int32_t int32_t;
typedef __int64_t int64_t;

进一步查看:bits/types.h
在线查看:https://elixir.bootlin.com/glibc/latest/source/posix/bits/types.h#L37

这是平台相关的定义,例如posix

typedef signed char __int8_t;
typedef unsigned char __uint8_t;
typedef signed short int __int16_t;
typedef unsigned short int __uint16_t;
typedef signed int __int32_t;
typedef unsigned int __uint32_t;
#if __WORDSIZE == 64
typedef signed long int __int64_t;
typedef unsigned long int __uint64_t;
#else
__extension__ typedef signed long long int __int64_t;
__extension__ typedef unsigned long long int __uint64_t;
#endif

b)进一步查看 bits/stdint-uintn.h
在线查看: https://elixir.bootlin.com/glibc/latest/source/bits/stdint-uintn.h

可以看到

typedef __uint8_t uint8_t;
typedef __uint16_t uint16_t;
typedef __uint32_t uint32_t;
typedef __uint64_t uint64_t;

进一步查看:bits/types.h
在线查看:https://elixir.bootlin.com/glibc/latest/source/posix/bits/types.h#L37
同a)

这样我们就大概知道在 posix 平台上的glibc里:

  • int8_t 实际上就是 signed char
    • signed char 一般简写为 char
  • uint8_t 实际上就是 unsigned char
  • int16_t 实际上就是 signed short int
    • short int 一般简写为 short
    • signed short int 一般简写为 short
  • uint16_t 实际上就是 unsigned short int
    • unsigned short int 一般简写为 unsigned short
  • int32_t 实际上就是 signed int
  • uint32_t 实际上就是 unsigned int

而对于 int64_tuint64_t 则需要判断当前系统是32位的还是64位的

  • 如果是64位,则实际上
    • __int64_t 就是 signed long int,一般 long int 简写为 long,从而 signed long int 简写为 long
    • __uint64_t 就是 unsigned long int 一般简写为 unsigned long
  • 如果在32位上,那么
    • __int64_t 就是 signed long long int 也就是 signed long long
    • __uint64_t 就是 unsigned long long int 也就是 unsigned long long

这样通常情况下,认为下面两组整数类型的定义是等价的是可以的:

使用基本整数类型定义,他们分别是 8 bytes, 16 bytes, 32 bytes, 64 bytes 的有符号整数和无符号整数:
char, short, int , long long,
unsigned char,unsigned short,unsigned int, unsigned long long

使用C99标准,使用<stdint.h>里的定义,则可以使用这组:
int8_t, int16_t, int32_t, int64_t,
uint8_t, uint16_t, uint32_t, uint64_t

--end--

posted @ 2023-10-13 22:36  ffl  阅读(145)  评论(0编辑  收藏  举报