linux tricks 之数据对齐。
转载:http://blog.chinaunix.net/uid-20608849-id-3027953.html
内核为了保持最大的兼容性和代码灵活性,不可能直接对某个数据类型定义它的大小范围。但是很多时候又要用到这些最大值最小值或者该数据类型可以表示的数据范围,比如初始化一个值为最大/小值,或者检验数据是否位于某个类型的范围内。
1 include/linux/kernel.h 2 #define USHORT_MAX ((u16)(~0U)) 3 #define SHORT_MAX ((s16)(USHORT_MAX>>1)) 4 #define SHORT_MIN (-SHORT_MAX - 1) 5 6 #define INT_MAX ((int)(~0U>>1)) 7 #define INT_MIN (-INT_MAX - 1) 8 #define UINT_MAX (~0U) 9 10 #define LONG_MAX ((long)(~0UL>>1)) 11 #define LONG_MIN (-LONG_MAX - 1) 12 #define ULONG_MAX (~0UL) 13 14 #define LLONG_MAX ((long long)(~0ULL>>1)) 15 #define LLONG_MIN (-LLONG_MAX - 1) 16 #define ULLONG_MAX (~0ULL)
内核通过C语言的强制转换来实现,首先定义无符号数的最大值,比如USHORT_MAX。然后去掉符号位可以得到该类型有符号的最大值,而最小值的绝对值则比最大值的大1,所以通过对有符号的最大值取反减1,就可以得到有符号的最小值。根据这一规则可以很容易写出char类型的相关数据大小。转换的原理从下图中可以更清晰的看出来:
根据Linux对short,int,long以及long long数据类型大小的定义,可以很容易定义出char型的数据大小,示例如下:
1 #include <stdio.h> 2 3 #define UCHAR_MAX ((unsigned char)(~0U)) 4 #define CHAR_MAX ((char)(UCHAR_MAX >> 1)) 5 #define CHAR_MIN (-CHAR_MAX - 1) 6 7 int main() 8 { 9 printf("UCHAR_MAX:\t%u\n", UCHAR_MAX); 10 printf("CHAR_MAX:\t%d\n", CHAR_MAX); 11 printf("CHAR_MIN:\t%d\n", CHAR_MIN); 12 13 return 0; 14 }
得到如下结果:
1 UCHAR_MAX: 255 2 CHAR_MAX: 127 3 CHAR_MIN: -128