C语言规范中对内置类型的最小长度有限制;因此,编译器必须确保
char
的长度至少为 8 位、int
32 位、long long
64 位等。
但是,当我实现内核的体系结构相关部分时,我需要一些具有 8 位、16 位、32 位或 64 位“确定长度”的类型。使用这些类型,我可以读取表格或写入 8 位和 16 位 I/O 端口,或 32 位和 64 位寄存器。现有的类型是否有保证长度? 当我在 Linux 源代码中查找此类类型定义(如
u32
或
u64
)时,我发现它们是由内置类型定义的:<uapi\asm-generic\int-ll64.h>
typedef __signed__ char __s8;
typedef unsigned char __u8;
typedef __signed__ short __s16;
typedef unsigned short __u16;
typedef __signed__ int __s32;
typedef unsigned int __u32;
typedef __signed__ long long __s64;
typedef unsigned long long __u64;
和
<linu\asm-generic\int-ll64.h>
typedef __s8 s8;
typedef __u8 u8;
typedef __s16 s16;
typedef __u16 u16;
typedef __s32 s32;
typedef __u32 u32;
typedef __s64 s64;
typedef __u64 u64;
内核使用此类类型来定义其他一些看起来具有确定长度的类型:
#ifdef CONFIG_PHYS_ADDR_T_64BIT
typedef u64 phys_addr_t;
#else
typedef u32 phys_addr_t;
#endif
或者说,在针对特定架构编译代码时,那些内置类型的长度可以保证吗?或者 Linux MakeFile 是否使用一些标志和编译选项来固定类型长度?
#include <stdint.h>
的行将其合并到代码中),该文件提供“固定宽度”整数类型的定义。
来自本 C11 标准草案7.20 整数类型<stdint.h>
1 标头<stdint.h>
声明了一组 具有指定宽度的整数类型,并定义相应的集合 的宏。它还定义了指定整数限制的宏 与其他标准头文件中定义的类型相对应的类型。
使用此标头,您可以访问
int64_t
和
uint8_t
等类型;来自相同的标准草案部分(我的第 3 节中的粗体斜体强调):
7.20.1.1 精确宽度整数类型注意:此“stdint.h”标头也在
1 typedef 名称intN_t
指定一个带符号的 宽度为 N、无填充位和二进制补码的整数类型 表示。因此,
表示这样一个有符号整数类型 正好8位的宽度。 2 typedef 名称int8_t
uintN_t
指定一个无符号 宽度为 N 的整数类型,没有填充位,因此,uint24_t 表示宽度恰好为 24 位的无符号整数类型。 3 这些类型是
可选。但是,如果实现提供宽度为 8、16、32 或 64 位的整数类型,无填充位,并且(对于有符号类型)具有二进制补码表示形式,则它应定义相应的 typedef 名称.