当前位置:嗨网首页>书籍在线阅读

03-可移植的数据类型

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

23.1.1 可移植的数据类型

C语言中的标准数据类型int、long的长度直接与平台相关,在驱动中,关键部分代码直接使用这些类型时需要特别小心。表23.1给出了在几个不同的平台下char、short、int、long、ptr、long long的长度。

表23.1 不同平台下char、short、int、long、ptr、long long的长度

| arch | char | short | int | long | ptr | long long | | :----- | :----- | :----- | :----- | :----- | :----- | :----- | :----- | :----- | | i386 | 1 | 2 | 4 | 4 | 4 | 8 | | Alpha | 1 | 2 | 4 | 8 | 8 | 8 | | armv4l | 1 | 2 | 4 | 4 | 4 | 8 | | ia64 | 1 | 2 | 4 | 8 | 8 | 8 | | M68K | 1 | 2 | 4 | 4 | 4 | 8 | | MIPS | 1 | 2 | 4 | 4 | 4 | 8 | | PaverPC | 1 | 2 | 4 | 4 | 4 | 8 | | Sparc | 1 | 2 | 4 | 4 | 4 | 8 | | Sparc64 | 1 | 2 | 4 | 4 | 4 | 8 | | x86_64 | 1 | 2 | 4 | 8 | 8 | 8 |

因此,在Linux系统中,针对不同的体系结构重新typedef出了u8、u16、u32、u64、s8、s16、s32、s64等类型。例如,在i386/arm下这些类型的定义如代码清单23.1所示,而在ppc64下这些类型的定义则如代码清单23.2所示,可见影响C语言基本数据类型大小的主要因素是CPU字长。

代码清单23.1 i386/arm平台下u8、u16、u32、u64、s8、s16、s32、s64的定义

1 typedef signed char s8;

2 typedef unsigned char u8;

3

4 typedef signed short s16;

5 typedef unsigned short u16;

6

7 typedef signed int s32;

8 typedef unsigned int u32;

9

10 typedef signed long long s64;

11 typedef unsigned long long u64;

代码清单23.2 ppc64平台下u8、u16、u32、u64、s8、s16、s32、s64的定义

1 typedef signed char s8;

2 typedef unsigned char u8;

3

4 typedef signed short s16;

5 typedef unsigned short u16;

6

7 typedef signed int s32;

8 typedef unsigned int u32;

9

10 typedef signed long s64;

11 typedef unsigned long u64;

由于u8、u16、u32、u64、s8、s16、s32、s64是被针对不同的体系结构单独定义的,因此,在任何平台下对其进行sizeof运算的结果都是不变的,是确定长度的数据类型。但是,这些类型都应该只在内核空间使用。在Linux用户空间中,如果要使用确定长度的数据类型,应该使用上述定义加“ ”的版本,如_ u8、 u16、 u32等。鉴于此,设备驱动中如果要向用户空间导出头文件,在头文件中也应该定义 sxx、 _uxx等数据类型。

上面给出的uxx、sxx、_ uxx、 _sxx类型定义都是Linux系统所特有的,为了更好地向其他平台移植,驱动中最好使用int8_t、int16_t、int32_t、uint8_t、uint16_t、uint32_t、int64_t、uint64_t这些C99标准确定长度类型。

Linux系统中定义了许多以_t为后缀的数据类型,这些类型用在内核的一些常用功能的实现中,如dma_addr_t、uid_t、gid_t、size_t、ssize_t、pid_t、loff_t等,这些类型的使用将使内核屏蔽实际数据类型间存在的差异。例如,file_operations中的read()、write()成员函数返回值为ssize_t类型,llseek()返回的是loff_t类型。此外,ssize_t、pid_t这些类型也被赋予了一些含义,这一点从名字就可以看出来,如pid_t是进程ID类型。