您的位置:首页 > 编程语言 > C语言/C++

C语言中微妙的bug(一)

2015-10-15 22:50 288 查看
  一、摘自《C专家编程_1.10 “安静的改变”究竟有多少安静》

     类型转换。

     在下面这个例子里,变量d下标值小1,这段代码的母的就是处理这种情况。但if表达式的值却不是真。为什么?是不是有Bug:

         

int array[] = { 23, 34, 12, 17, 204, 99, 16 };
#define TOTAL_ELEMENTS (sizeof(array)/sizeof(array[0]))

main()
{
int d = -1, x;
/* ... */

if(d <= TOTAL_ELEMENTS - 2)
x = array[d+1];
/* ... */
}


    TOTAL_ELEMENTS所定义的值是unsigned int类型(因为sizeof()的返回类型是无符号类型数)。if语句在signed int和unsigned int之间测试相等性,所以d被升级为unsigned
int类型,-1转换成unsigned int的结果将是一个非常巨大的正整数,致使表达式的值为假。这个bug在ANSI C中存在,而如果K&K C的某种编译器的sizeof()的返回值是无符号数,那么这个Bug也存在。要修正这个问题,只要对TOTAL_ELEMENTS进行强制类型转换即可:

if(d < (int)TOTAL_ELEMENTS - 2)
        对无符号类型的建议

    尽量不要在你的代码中使用无符号类型,以免增加不必要的复杂性。尤其是,不要仅仅因为无符号不存在负值(如年龄、国债)而用它来表示数量。

    尽量使用像int那样的有符号数类型,这样在涉及升级混合类型的复杂细节时,不必担心边界情况(如-1被翻译为非常大的正数)

    只有在使用位段和二进制掩码时,才可以使用无符号数。应该在表达式中使用强制类型转换,使操作数均为有符号数或者无符号数,这样就不必由编译器来选择结果的类型。 

二、switch的另外一个问题-----break中断了什么

    测试代码:

     1 #include<stdio.h>
2
3 int main()
4 {
5 int a = 2, b = 0;
6 switch(a)
7 {
8 case 1:
9 b = 1;
10 break;
11 case 2:
12 if(2 == a)
13 {
14 break;(这里的break的意图是跳到16行)
15 }
16 b = 2;(意图是跳到这里)
17 break;
18 default:
19 b = 3;
20
21 }(但事实上是直接跳到这里了)
22 printf("b=%d\n",b);
23
24 return 0;
25 }       运行结果:b=0;
       这个bug导致了,AT&T导致了整个长话网络的瘫痪。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: