您的位置:首页 > 其它

glibc之数据类型定义分析

2011-06-24 13:16 465 查看
本文主要涉及到的库文件位于/usr/include/bits目录下,文件包括wordsize.h,types.h,typesizes.h 等文件。

wordsize.h中主要定义了当前机器的字大小。内容如下:

...

#define __WORDSIZE 32

...

这里的宏应该是安装系统的时候,确定的机器字的大小,然后才生成对应的宏。这个宏会在types.h中作为判定条件,从而定义相应数据类型。我们可以看下types.h文件有如下内容:

99 #define __S16_TYPE short int

100 #define __U16_TYPE unsigned short int

101 #define __S32_TYPE int

102 #define __U32_TYPE unsigned int

103 #define __SLONGWORD_TYPE long int

104 #define __ULONGWORD_TYPE unsigned long int

//以上类型定义与机器字长度无关

105 #if __WORDSIZE == 32

106 # define __SQUAD_TYPE __quad_t

107 # define __UQUAD_TYPE __u_quad_t

108 # define __SWORD_TYPE int

109 # define __UWORD_TYPE unsigned int

110 # define __SLONG32_TYPE long int

111 # define __ULONG32_TYPE unsigned long int

112 # define __S64_TYPE __quad_t

113 # define __U64_TYPE __u_quad_t

114 /* We want __extension__ before typedef's that use nonstandard base types

115 such as `long long' in C89 mode. */

116 # define __STD_TYPE __extension__ typedef //如果机器为32位,我们需要使用扩展数据类型定义宏

117 #elif __WORDSIZE == 64

118 # define __SQUAD_TYPE long int

119 # define __UQUAD_TYPE unsigned long int

120 # define __SWORD_TYPE long int

121 # define __UWORD_TYPE unsigned long int

122 # define __SLONG32_TYPE int

123 # define __ULONG32_TYPE unsigned int

124 # define __S64_TYPE long int

125 # define __U64_TYPE unsigned long int

126 /* No need to mark the typedef with __extension__. */

127 # define __STD_TYPE typedef

//如果机器为64位,我们不需要在typedef前加扩展宏
__extension__,后面的__STD_TYPE 即表示typedef

128 #else

129 # error

130 #endif

上面的# define __SQUAD_TYPE __quad_t表示当机器为32位,但是又要表示64位数据时,我们可以通过如下方法定义:

/* quad_t is also 64 bits. */

52 #if __WORDSIZE == 64

53 typedef long int __quad_t;

54 typedef unsigned long int __u_quad_t;

55 #elif defined __GLIBC_HAVE_LONG_LONG

56 __extension__ typedef long long int __quad_t;

57 __extension__ typedef unsigned long long int __u_quad_t;

58 #else //32位机器

59 typedef struct

60 {

61 long __val[2];

62 } __quad_t;

63 typedef struct

64 {

65 __u_long __val[2];

66 } __u_quad_t;

67 #endif

131 #include <bits/typesizes.h> /* Defines __*_T_TYPE macros. */

//将typesizes.h包含进来,因为里面通过定义了所有的 __*_T_TYPE宏,而这些宏都是下面的类型定义的基础

135 __STD_TYPE __UID_T_TYPE __uid_t; /* Type of user identifications. */

136 __STD_TYPE __GID_T_TYPE __gid_t; /* Type of group identifications. */

143 __STD_TYPE __PID_T_TYPE __pid_t; /* Type of process identifications. */

155 __STD_TYPE __KEY_T_TYPE __key_t; /* Type of an IPC key. */

注意这里的__STD_TYPE = typedef 不再是宏定义,而是类型定义

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

我们可以查看typesizes.h文件,内容如下:

1 /* bits/typesizes.h -- underlying types for *_t. Generic version.

这个文件用来定义类似于*_t的基本类型(underlying type)

.....

2 */

19

20 #ifndef _BITS_TYPES_H

21 # error "Never include <bits/typesizes.h> directly; use <sys/types.h> instead."

22 #endif

23

24 #ifndef _BITS_TYPESIZES_H

25 #define _BITS_TYPESIZES_H 1

26

27 /* See <bits/types.h> for the meaning of these macros. This file exists so

28 that <bits/types.h> need not vary across different GNU platforms.

宏定义参考types.h中的宏定义,如__S32_TYPE 这个是在types.h中定义的。

#define __S32_TYPE int

至于为什么要这么交叉定义,是为了使types.h不因为平台而发生变化。

因为,如果不同的平台的话,我们只需要改变typesizes.h就可以了。

*/

31 #define __UID_T_TYPE __U32_TYPE

32 #define __GID_T_TYPE __U32_TYPE

39 #define __PID_T_TYPE __S32_TYPE

53 #define __DADDR_T_TYPE __S32_TYPE

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

我们以__key_t为例子来寻定义的蛛丝马迹:

1.__STD_TYPE __KEY_T_TYPE __key_t //bits/types.h

2.#define __KEY_T_TYPE __S32_TYPE //bits/typesizes.h

3.#define __S32_TYPE int

从3-2-1就是我们的: typedef int __key_t ;

至于我们看到的ipc中的key_t数据类型,则又是在__key_t基础上定义的,我们可以在ipc.h中找到这个定义:

47 #ifndef __key_t_defined

48 typedef __key_t key_t;

49 # define __key_t_defined

50 #endif

所以,我们在linux c 编程里面经常看到的那些莫名奇妙的数据类型,基本都可以通过以上方式找到最终的基本数据类型。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: