看这么两行代码:
int i = -1;
cout << (char(i) == unsigned char(i)) << endl;
在VC6.0下,永远输出0。而下面这两行代码也永远输出0
int i = 255;
cout << (char(i) == unsigned char(i)) << endl;
而实际上,以上两个代码中,char(i)和unsigned char(i)具有的内存布局都是完全相同的。由于整型之间的类型转换遵循这样的原则:当目标类型比原类型短的时候,直接截断原类型。而当目标类型较长,则无符号类型会直接在高位补0,有符号类型在高位补符号位。
在VC6下,而当两个长度相同,并且具有相同内存布局的整型相比较的时候,编译器做如下的工作:
首先两者长度<=int的长度的时候,全部转化为int,然后实施比较。
所以char(-1)转化的结果是0xFFFFFFFF,而unsigned char(-1)转化的结果是0x000000FF。两者作为int比较的时候,自然是不相等的。
但是,特别的,当两者长度刚好是int长度的时候,比较的结果仅取决于内存布局,而有符号和无符号的转化也不会改变内存布局。
这个事实引起了一个问题,当我们使用char/unsigned char,short/unsigned short这类比int短的类型的时候,无符号类型的变量是绝对不会和有符号的-1相等的,而使用int的时候,int(-1)和unsigned int(-1)则是完全相等的。这使得修改变量类型会引发比较结果的变化,尤其是在做变量扩展,或者在模板代码中这个问题有可能会引发难以觉察的错误。
对这个问题的建议是:永远都不要进行有符号类型和无符号类型之间的数值比较,不同长度的类型之间的比较也要尽量避免。
--------------------next---------------------
阅读(308) | 评论(0) | 转发(0) |