C语言中微妙的bug(一)
2015-10-15 22:50
288 查看
一、摘自《C专家编程_1.10 “安静的改变”究竟有多少安静》
类型转换。
在下面这个例子里,变量d下标值小1,这段代码的母的就是处理这种情况。但if表达式的值却不是真。为什么?是不是有Bug:
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进行强制类型转换即可:
尽量不要在你的代码中使用无符号类型,以免增加不必要的复杂性。尤其是,不要仅仅因为无符号不存在负值(如年龄、国债)而用它来表示数量。
尽量使用像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导致了整个长话网络的瘫痪。
类型转换。
在下面这个例子里,变量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导致了整个长话网络的瘫痪。
相关文章推荐
- C++中虚函数的用法详细讲解
- c++ primer第五版(中文)习题答案 第十章第五节第二三小节-算法形参合命名规范
- C语言入门----字符
- [c++] LeetCode longest substring without repeating characters问题
- C++中文件的读写
- gen-cpp/.deps/ChildService.Plo: No such file or directory
- C++实现RTMP协议发送H.264编码及AAC编码的音视频,摄像头直播
- c++ primer第五版(中文)习题答案 第十章第五节第一小节-5类迭代器
- C++学习笔记(第二篇)
- 非递归学习树结构(六)--RB-Tree(红黑树)
- c++primer——模板,标准库特殊设施
- C++设计模式——单例模式
- 浅析C++中的重载运算符(重点是重载+=)
- 浅析C++中的重载运算符(重点是重载+=)
- Isomorphic Strings
- 编译器定义的C/C++语言各种基本数据类型的取值范围
- C++编程有趣的标题1 于1~9填写的运算结果的中间符号等于100
- C++库一览
- win7 下mingw64 编译boost 1.59
- C/C++中函数参数传之指针形参