Linux 标准 C 类型的使用

尽管大部分程序员习惯自由使用标准类型, 如 int 和 long, 编写设备驱动需要一些小心 来避免类型冲突和模糊的 bug.

这个问题是你不能使用标准类型, 当你需要"一个 2-字节 填充者"或者"一个东西来代表 一个 4-字节 字串", 因为正常的 C 数据类型在所有体系上不是相同大小. 为展示各种 C 类型的数据大小, datasize 程序已包含在例子文件 misc-progs 目录中, 由 O' Reilly's FTP 站点提供. 这是一个程序的样例运行, 在一个 i386 系统上(显示的最后 4 个类型在下一章介绍):

morgana% misc-progs/datasize

arch Size: char short int long ptr long-long u8 u16 u32 u64 i686           1    2     4   4    4   8         1  2   4   8

这个程序可以用来显示长整型和指针在 64-位 平台上的不同大小, 如同在不同 Linux 计 算机上运行程序所演示的:

arch  Size:

char

short

int

long

ptr

long-long

u8

u16

u32

u64

i386

1

2

4

4

4

8

1

2

4

8

alpha

1

2

4

8

8

8

1

2

4

8

armv4l

1

2

4

4

4

8

1

2

4

8

ia64

1

2

4

8

8

8

1

2

4

8

m68k

1

2

4

4

4

8

1

2

4

8

mips

1

2

4

4

4

8

1

2

4

8

ppc

1

2

4

4

4

8

1

2

4

8

sparc

1

2

4

4

4

8

1

2

4

8

sparc64

1

2

4

4

4

8

1

2

4

8

x86_64

1

2

4

8

8

8

1

2

4

8

注意有趣的是 SPARC 64 体系在一个 32-位 用户空间运行, 因此那里指针是 32 位宽, 尽管它们在内核空间是 64 位宽. 这可用加载 kdatasize 模块(在例子文件的 misc- modules 目录里)来验证. 这个模块在加载时使用 printk 来报告大小信息, 并且返回一 个错误( 因此没有必要卸载它 ):

kernel: arch Size: char short int long ptr long-long u8 u16 u32 u64 kernel: sparc64    1    2     4   8    8   8         1  2   4   8

尽管在混合不同数据类型时你必须小心, 有时有很好的理由这样做. 一种情况是因为内存 存取, 与内核相关时是特殊的. 概念上, 尽管地址是指针, 内存管理常常使用一个无符号 的整数类型更好地完成; 内核对待物理内存如同一个大数组, 并且内存地址只是一个数组 索引. 进一步地, 一个指针容易解引用; 当直接处理内存存取时, 你几乎从不想以这种方 式解引用. 使用一个整数类型避免了这种解引用, 因此避免了 bug. 因此, 内核中通常的 内存地址常常是 unsigned long, 利用了指针和长整型一直是相同大小的这个事实, 至少 在 Linux 目前支持的所有平台上.

因为其所值的原因, C99 标准定义了 intptr_t 和 uintptr_t 类型给一个可以持有一个 指针值的整型变量. 但是, 这些类型几乎没在 2.6 内核中使用.

猜你喜欢

转载自www.cnblogs.com/fanweisheng/p/11146082.html