📄 chapter1.html
字号:
<html><head><title>Writing Bug-Free C Code: Understand Why Bugs Exist</title></head><body><center><font size="+3">Chapter 1: Understand Why Bugs Exist</font><br><a href="index.html">Writing Bug-Free C Code</a><br></center><br><center><table><tr><td valign=top><small><a href="#smallvslarge">1.1 Small versus Large Projects</a><br><a href="#toomuchdata">1.2 Too Many Data Structures in Include Files</a><br><a href="#noscale">1.3 Using Techniques That Do Not Scale</a><br><a href="#globalinfo">1.4 Too Much Global Information</a><br><a href="#debugger">1.5 Relying on Debuggers</a><br><small></td><td width=30> </td><td valign=top><small><a href="#fixsymptom">1.6 Fixing the Symptom and Not the Problem</a><br><a href="#unmaintainable">1.7 Unmaintainable Code</a><br><a href="#debugkernel">1.8 Not Using the Windows Debug Kernel</a><br><a href="#summary">1.9 Chapter Summary</a><br></small></td></tr></table></center><br><br>Why do bugs exist and where in the development cycle do they creep in?Spending time and effort on the problem of understanding why bugs exist is the first step to writing bug-free code. The second step is to take action and institute policies that eliminate the problem or help detect the problem. Most important, make sure the entire programming staff knows about and understands the new policies. <blockquote><table bgcolor="#E0E0E0" border=1 cellpadding=2 cellspacing=0><tr><td> The first step in writing bug-free code is to understand why bugs exist. The second step is to take action. </tr></td></table></blockquote>A good friend of mine who works at a different company started to use run-time parameter validation in the modules that he wrote and the code that he modified. Run-time parameter validation is a good idea. However, management and other programmers at the site were reluctant to make this programming methodology mandatory. Well, one day my friend was modifying some existing code on the project and while he was at it, he added parameter validation to the functions that he had modified. He tested the code and checked it back into the source-code control system. A few weeks later the code started to display parameter errors from code that it had called that had been written years ago. Unbelievably, some programmers wanted the parameter validation removed. After all, they reasoned, code that once worked was now producing errors, so it must be the new parameter validation code, not the old existing code. <br><br>This is an extreme example, but it demonstrates that everyone involved with a project must fully understand new programming methodologies instituted in the middle of a programming project.<br><a name="smallvslarge"><br></a><big><b>1.1 Small versus Large Projects</b></big> <br><br>What if you needed to write a hex dump utility to be called DUMP? The program takes as an argument on the command line the name of the file you wish to display in hex. Would it be written without a single bug? Yes, probably so, but why? Because the task is small, well defined and isolated. <br><br>So what happens when you are asked to work on project ALPHA, a contract programming project your company is working on for another company? The project is several hundred thousand lines long and has ten programmers already working on the project. The deadlines are approaching and the company needs your programming talent. Do you think you could jump right in and write new code without introducing bugs into the project? I couldn't, at least not without the proper programming methodologies in place to catch the programming errors any beginner on the project is bound to make. <br><br>Think of the largest project you have worked on. How many include files were there and what did the include files contain? How many source files were there and what did they contain? You had no problem working on the DUMP utility, so what makes the large project so difficult to work on? Why is the large project not simply like working on ten or one hundred small projects? <blockquote><table bgcolor="#E0E0E0" border=1 cellpadding=2 cellspacing=0><tr><td> Programming methodologies must make it easy for new programmers to jump into a project without introducing a slew of new bugs. </tr></td></table></blockquote>Let's examine your small programming project. It consists of a couple of source files and a couple of include files. The include files contain function prototypes, data structure declarations, #define's, typedef's and whatever else. You have knowledge of everything, but because the number of files is relatively small, you can handle it all. Now, multiply this by ten or one hundred times for the large project and all of a sudden the project becomes unmanageable. <br><br>You have too much information in the include files to manage and now the project is getting behind, so you add more people to the project to get it completed faster. This only compounds the problem, because now you have even more people adding information to the pool of information that everyone else needs to learn and know about. It is a vicious cycle that all too many projects fall into.<br><a name="toomuchdata"><br></a><big><b>1.2 Too Many Data Structures in Include Files</b></big> <br><br>We can all agree that one major problem in large projects is that there is too much information to become familiar with in a short period of time. If you could somehow eliminate some of the information, this would make it easier, since there would be less information to become familiar with. <br><br>The root of the problem is that there is too much information placed into include files, the biggest contributor being data structure declarations. When you start a project, you place a couple of declarations in the include file. As the project continues, you place more and more declarations in the include file, some of which refer to or contain previous declarations. Before you know it, you have a real mess on your hands. The majority of your source files have knowledge of the data structures and directly reference elements from the structures. <blockquote><table bgcolor="#E0E0E0" border=1 cellpadding=2 cellspacing=0><tr><td> A technique that helps eliminate data structures from include files needs to be found. </tr></td></table></blockquote>Making changes in an environment where many data structures directly refer to other data structures becomes, at best, a headache. Consider what happens when you change a data structure. This change forces you to recompile every source file that directly, or more importantly indirectly, refers to the changed data structure. This happens when a source file refers to a data structure that refers to a data structure that refers to the changed data structure. A change to the data structure may force you to modify some code, possibly in multiple source files. <br><br>The <a href="chapter4.html">class methodology §4</a>solves this data structure problem.<br><a name="noscale"><br></a><big><b>1.3 Using Techniques That Do Not Scale</b></big> <br><br>As you have just seen, large projects have problems all their own. Because of this, you must be careful in selecting programming methodologies that work well in small projects as well as in large programming projects. In other words, a programming methodology must scale or work with any project size. <blockquote><table bgcolor="#E0E0E0" border=1 cellpadding=2 cellspacing=0><tr><td> Programming methodologies must work equally well for both small and large projects. </tr></td></table></blockquote>Let's say that Joe Programmer institutes a policy that all data declarations must be declared in include files so that all source files have direct access to the data structures. He reasons that by doing this, he will gain a speed advantage over his competition and his product will be superior. <br><br>This may work for the first release of his product, but what happens when the size of the project grows to the point that it becomes unmanageable because there are too many public data declarations? His job is at stake. The programming methodology Joe chose worked great for the small project when it started, but it failed miserably when the project grew. And all successful small projects grow into large projects. <br><br>Make sure the programming methodologies that you develop work equally well for both small and large projects.<br><a name="globalinfo"><br></a><big><b>1.4 Too Much Global Information</b></big> <br><br>Global variables (variables known to more than one source file) should be avoided. Their usage does not scale well to large applications. Just think what eventually happens in a large application when the number of global variables gets larger and larger. Before you know it, there are so many of them that the variables become unmanageable. <br><br>Whenever you are about to use a global variable, ask yourself why you need direct access to the variable. Would a function call to the module where the variable is defined work just as well? Most of the time the answer is yes. If the global variable is modified (read and written), then you should be asking yourself how the global variable is being acted upon and if it be better to specify what to do through a function call, leaving the how to the function. <blockquote><table bgcolor="#E0E0E0" border=1 cellpadding=2 cellspacing=0><tr><td> Variables known to more than one source file should be avoided. </tr></td></table></blockquote>Some global variables are OK, but my experience has been that only a handful are ever needed, no matter how large a project gets.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -