1. 有符号和无符号数的差别
a. 对无符号数,永远不要加小于零的判断
unsigned int i=-1;
if(i<0)
{
xxxx;
}
上面if语句里永远执行不到。
b. 指针和有符号数相加
unsigned char ccc;
unsigned char offset_table[256] = {0,1,2,3,4,.........253,254,255};
char p[] = {0x89,0x88,0x87,0x86,0x85,0x84,0x83};
c = offset_table(p[1]);
c并不是从offset中查出来的,因为c是有符号的,其实上面的c值是 *(offset_table+0xffffff88).
看看汇编就明白了,一个同事处理网络上接受的数据,判断数据的时候出现了这个错误,她的代码比上面的
还复杂,而且是一系列的宏定义的,和其他逻辑交织在一起,害的我帮她查了好一会儿才。正确的做法是
把p定义为unsigned char p[],。
c. 不要小看某个函数未声明的编译警告
"warning, get_page_width undefined, assuming extern returning int"
这个警告很多人不注意,编译器认为是返回int型的,就会有上面b提到的问题,同时,如果函数
get_page_width()在函数实体的地方返回值定义为short get_page_width()(或
char get_page_width() ),那么函数返回的地方在汇编里eax寄存器的高16位可能是不是0,或随机的
值,假设高16的值是0xffff, get_page_width值是1,高 那么int i = get_page_width(), i的值就是
0xffff0001, 显然不是你想要的值。
符号转换的含义
以前以为都是尽量的多打括号,多转换,再看别人的定点浮点转换发现的bug。
u32 v = 0x7FFF7FFF;
s32 coord0 = ((s16)((v&0x3FF)<<6))>>6;
则coord0 = –1; 会进行符号位的扩展。s16会强制(v&0x3FF)<<6是16位符号数,所以再右移的时候会按着s16t进行符号扩展移位。
u32 v = 0xF000FFFF; s16 co = v>>20;
则co = 0x0F00; 不会进行符号位的扩展。
short c = 0x0FFF;
int i = (c<<8);
则i = 0x000FFF00
short c = 0x0FFF;
int i = (short)(c<<8);
则i = 0xFFFFFF00