保持良好的调试心态!
取得正确地错误信息是成功的而且高效的调试的关键。
获得错误信息的方法:
1。通过测试人员提供的消息(错误报告)。需要为测试人员提供错误报告表单和详细的使用说明;
2。错误重现。测试人员必须在重现错误的过程中起到积极作用。刚发现错误的时候是错误重现的最佳时期。
3。错误报告表单的信息。错误表单有一定的格式。错误表单需要详细的说明书,用于指导测试人员正确填写。
通过系统控制面板的设置,使得在win2000系统兰屏下自动将兰屏上信息记录到minidump或者Memory.dump。单击“高级”标签,然后单击“启动和故障恢复”,选择“小内存转储”或者“完全内存转储”。
分析错误信息:
错误代码,测试人员看到的错误,也就是最后一步报告的情况。
征兆代码,可能导致观察到的失败的细节代码。
原因代码,征兆的潜在原因。
解决代码,需要更改的,可以消除错误而不引入新错误的明确的代码。
问题的征兆只是最尖但的错误的原因,对于比较难的错误,必须跟踪进去寻找内在原因。
使用调试器分析。
动脑分析。
演绎推理,从事实得到结论。
排除的过程:
1。收集有关的事实,
2。确定可能的解释。
3。排除与事实不一致的解释。
4。精炼剩下的解释。
5。用经验来验证剩下的解释。
6。假设剩下的解释是真的。
归纳推理常用于从特殊到一般。
消除错误:
有这样一段代码:
CSizeDialog dialog;
dialog.m_size = m_size;
if(dialog.DoModal() == IDOK)
{
int tempVar1,tempVar2,tempVar3,
m_size = dialog.m_size;
.......
}
if(newblock)
{
.......
}
作者提到,不管从对话框输入何值,m_size变量的值都不改变,因为tempVar3不该为“,”,应该为“;”,这种解释当然正确,但我觉得这是由于编写代码的不规范造成,因此,在编写代码时,一次只定义一个变量。
海森堡不确定定理:“位置越精确,当时的动量就越不精确。”该原理指出,对某种现象的绝对的观察和测量是不可能的,这样就导致不确定性。
在调试器的交互环境中运行程序会改变程序的行为。不要在还不明白做什么的情况下就去编程序。
保守维护的规则(维护阶段):
1。如果不是错误代码,一定不要修改。不敢它是多么丑陋,多么让你看着不顺眼。
2。如果是错误代码,修改并完善。
开发无错误软件的最好方法是采取负责的态度。
松耦合的程序对程序测试十分重要。
注意编程风格。
结构良好的代码具有更加有用的调用栈。
要写出能被“人”读懂的代码。
用const代替#define来创建常量。
用enum代替#define来创建常量集合。
用内联函数来代替#define宏。
用new和delete代替malloc和free。
用输入输出流(iostreams)代替stdio。
new不仅分配内存,还调用了类的构造函数;delete先调用对象析构函数然后喜爱释放内存。
要在头文件中声明所有共享的外部符号,而且保留函数原型中的参数名。
书中37页,变量初始化问题。
位掩码
布尔表达式应该检查是否为假而不是检查是否为真。
溢出,使用Limits.h中定义的最小值和最大值来作为整型数据类型的大小限制。
在做除法时,如果不能保证除数不为0.0,那就要处理可能要出现的异常。
不要匆忙使用强制类型转换,为了保证安全性,每一个强制类型转换都需要你手工进行类型检测。
避免使用强制类型转换的技术:
避免使用多态数据类型;
使用更加广泛的基类;
提供特殊的存取函数;
让编译器隐式处理类型;
如果你在visual
c++中使用dynamic_cast,记住要在project设置里面选择Enable time Type
Information选项。
在程序中仔细地使用const是一种好方法,能帮助编译器在编译时刻帮你发现
错误。
如果循环变量的增加操作在每次循环的时候必须执行的话,那么就使用for语
句而不是while语句。
构造函数中的虚函数并不像一般的虚函数,也就是说,如果基类的构造函数
调用了一个虚函数,调用的实际是虚函数的基类版本,而不是重载后的派生类版
本。
一定要保证析构函数的异常在析构函数中得到处理。
big three 法则:如果一个类需要一个析构函数,或者一个拷贝构造函数,或
者一个复制运算符,那么它就三个都需要。
一旦构造函数分配了资源,编译器对这些函数的实现就会肯定会出错。(?)
尽量采用编译时刻检查而不是运行时刻检查。
总是使用/W4警告级别。
在调试版本里总是使用/GZ编译选项。
抑制假的警告消息:
使用宏 #ifdef _DEBUG
#define UNUSED(x)
#else
#define UNUSED(x) x
#endif
#define UNUSED_ALWAYS(x) x
#pragma warning编译器指示
/WX编译选项(把所有的警告都当成错误来对待)
通过使用断言来自动检测运行时刻错误。
断言是用来发现运行时刻错误的。断言发现的错误是关于程序实现方面的,
而不是诸如用户输入错误、资源分配错误、文件系统错误或硬件错误等其他类型
的错误。
断言中的布尔表达式显示的是某个对象或者状态的有效性,而不是正确性。
断言在条件编译后只存在调试版本里,而不是发布版本里。
断言不能包含程序代码,也不能有副作用。
断言是为了给程序员而不是用户提供信息。
断言类型(66)
使用最能匹配你的数据的断言。
防御式编程。
不管使用什么技术,垃圾输入都不应该导致垃圾输出。
需要防御性的编程的标准问题包括:错误的输入数据、内存或者硬盘空间不
够、不能打开一个文件、外设不能访问、网络连接不上或者甚至程序中还有错误
。
断言不是错误处理的替代品。