使用size_t和ssize_t主要是为了提高程序的可移植性,size_t一般用于计数缓冲区大小这种非负的场景,而对于像read、write等函数来说,可能失败返回负数的时候用ssize_t。
转自lmx并在实践的基础上稍有改动。
对于赶时间的朋友,只看第一段就好了。
首先,我非常肯定以及确定的告诉你ssize_t是有符号整型,在32位机器上等同于int,在64位机上等同于long int,有没有注意到,它和long数据类型有啥区别?其实就是一样的。size_t就是无符号型的ssize_t,也就是unsigned long/unsigned int(在32位下),不同的编译器或系统可能会有差别,主要是因为在32位机器上int和long是一样的。在64位没有测试,但是参见百度百科,size_t在64位下是64位,那么size_t的正确定义应该是typedef unsigned long size_t。
下面从源文件中查找ssize_t和size_t的定义。
实验环境:Red Hat Linux 3.2.2-5
ssize_t
1.首先执行locate sys/types.h,用vim找到ssize_t的位置。
#ifndef __ssize_t_defined
typedef __ssize_t ssize_t;
#define __ssize_t_defined
2.再搜索__ssize_t就没有任何有价值的信息了,观察文件发现,该文件还包含了其他头文件,在这个typedef之前有features.h和bits/types.h。打开后发现在bits/types.h这个文件中有__ssize_t的定义。
typedef __SWORD_TYPE __ssize_t
3.进一步查找__SWORD_TYPE的定义,找到如下代码。
#if __WORDSIZE == 32
# define __SWORD_TYPE int
#if __WORDSIZE == 64
# define __SWORD_TYPE long int
4.再进一步到bits/wordsize.h查找到__WORDSIZE
#define __WORDSIZE 32
__WORDSIZE就是表示计算机系统是几位的。
综上ssize_t在32位机器上等同于int
size_t
在/usr/lib/gcc-lib/i386-redhat-linux/3.2.2/include/stddef.h文件中有如下代码
#idndef __SIZE_TYPE__
#define __SIZE_TYPE__ long unsigned int
#endif
#if !(defined (__GNUG__) && defined (size_t))
typedef __SIZE_TYPE__ size_t
#ifdef __BEOS__
typedef long ssize_t;
可以肯定的是size_t是无符号整型,至于是long还是int可能不同的编译器有不同的定义。
一个基本的无符号整数的C/C++类型。它是sizeof操作符返回的结果类型。该类型的大小可选择,因此它可以存储在理论上是可能的任何类型的数组的最大大小。
参考文献
http://baike.baidu.com/view/3236587.htm
http://www.delorie.com/gnu/docs/glibc/libc_239.html