Reading Notes: Writing solid code (1 ):
Http://www.cnblogs.com/soroman/archive/2007/08/06/845465.html
Reading Notes: Writing solid code (2 ):
Http://www.cnblogs.com/soroman/archive/2007/12/22/1010870.html
Go On Writting solid code...
-----------------------------------
Chapter 4 step through your code
Check yourCode
-----------------------------------
Summary:
The best way to find Bugs is to step through all new code in a debugger. by stepping through each instruction with your focus on the data flow, you can quickly detect problems in your expressions and algorithms. keeping the focus on the data, not the instructions, gives you a second, very different, view of the Code. stepping through code takes time, but not nearly as much as most programmers wowould perform CT it.
Overview:
The best way to find the bugs is to check all new code row by row in the debugger. By checking each instruction and paying attention to the data flow, you can quickly detect statements andAlgorithm.
Focusing on data rather than instructions can give you another way of understanding the code. Line-by-line check code takes time, but there is not a vast majorityProgramPeople think that it takes so much time.
4.1.don't wait until you have a bug to step through your code.
Do not check your code until a bug occurs.
[Note] What is the best way to write code without bugs? It is to actively check the newly added or modified code, observe their execution, and verify that each instruction has done what you want to do.
The problem with black box testing is that you don't know what happened in the box. Checking code can be said to be a white-box test, which is the responsibility of the programmer. Click a breakpoint and observe the data. Then you will find the bugs.
4.2.step through every code path.
Check the path of each code.
[Note] except if-Else and switch path, &, | ,? : Also contains multiple paths. There are also bugs in the error handling branch that are hard to find, because there are few opportunities to enter the branch, so pay attention to them.
4.3.as you step through code, focus on dataflow.
When checking the code, pay attention to the data flow.
[Note] the real power of checking the code is to track the data flow. Therefore, many buckets can be found:
Overflow and underflow bugs
Data conversion bugs
Off-by-one bugs
Null Pointer bugs
Bugs using garbage memory (oxa3 bugs)
Assignment bugs in which you 've used = instead of =
Precedence bugs
Logic bugs
4.4.source level debuggers can hide execution details. Step through critical code at the instruction level.
Source codeThe level debugger may hide the running details. Check important code at the command level.
[Note] For example, if you are on a walk through Complex Condition Statement (such as include & or |), you can at the command level (or assembly level, the relationship between Assembly statements and machine commands)
Observe to get the results of all the branches, which may be inconvenient at the source code level.
-----------------------------------
Chapter 5 candy machine interfaces
Candy machine interface
-----------------------------------
Summary:
It's not enough that your functions be bug-free; functions must be easy to use without introducing unexpected bugs. If Bug rates are to be affected Ced,
Each function needs to have one well-defined purpose, to have explicit single-purpose inputs and outputs, to be readable at the point where it is
Called, and ideally to never return an error condition. Functions with these attributes are easy to validate using assertions and debug code, and they minimize the amount of error handling code that must be written.
Overview:
It is not enough to only ensure that your function itself has no bugs. The function must be easy to use and will not introduce unexpected bugs (you do not have enough bugs, you still need to use it without any bugs ). To reduce the bug occurrence rate, each function requires a definition.
A good purpose requires explicit input and output for a single purpose, good readability at the place where it is called, and ideally no error is returned. Functions with these attributes can easily be verified through assertions and debugging code, which reduces the required error handling code.
Guidelines:
5.1.make it hard to ignore error conditions. Don't bury error codes in return values.
Do not ignore errors easily. Do not include error codes in the returned values.
[Note] function interfaces such as getchar and malloc are not good:
Getchar returns an integer. If an error occurs,-1 (EOF) is returned. It is not good to put all the information in the returned value. If a system of char type is unsigned, that is, no-1 is returned, it cannot be known when getchar fails.
Malloc returns the pointer. If the pointer fails, 0 is returned.
Improved the getchar interface:
If a new char is successfully read, true is returned; otherwise, false is returned. Char can be returned from the parameter.
5.2.always look for, and eliminate flaws in your intefaces.
Keep searching for and reducing flaws from your interface.
[Note] the hidden danger of the following code is that if realloc fails, pbbuf = NULL and the original memory block pointed by pbbuf will be lost. 1 Pbbuf = ( Byte * ) Realloc (pbbuf, sizenew );
2 If (Pbbuf ! = Null)
3 /**/ /*Use/initialize the larger buffer*/
Improved interface: 1 Flag fresizememory ( Void ** GMM, size_t sizenew)
2 {
3 Byte ** Ppb = ( Byte ** ) GMM;
4 Byte * Pbnew;
5 Pbnew = ( Byte * ) Realloc ( * Ppb, sizenew );
6 I f (pbnew ! = Null)
7 * Ppb = Pbnew;
8 Return (Pbnew ! = Null );
9 }
In this way, even if the pointer fails, the original pointer will not be damaged.
5.3.don't write multipurpose functions. Write separate functions to allow stronger argument validation.
Do not write functions that contain multiple purposes. Separate (objective) Write functions to allow stronger parameter checks.
5.4.don't be wishy-Policy. Define explicit function arguments.
Not formal. Define explicit function parameters.
[Note] refer to the following functions: 1 Char * Copysubstr ( Char * Strto, Char * Strfrom, size_t size)
2 {
3 Char * STR start = Strto:
4 While (Size -- > 0 )
5 * Strto ++ = * Strfrom ++ ;
6 * Strto = ' \ 0 ' ;
7 Return (Strstart );
8 }
The size of the parameter is not verified in the function. For size = 0, the function can jump out, but when the size is greater than the length pointed to by strfrom, the bug occurs, in addition, the caller needs to work hard to identify bugs.
Sometimes it is worthwhile to allow a meaningless parameter, such as size = 0, because it can reduce the external testing of callers. However, if the caller has very few or never passed in 0 size, do not use handle 0 size because it may hide bugs, so use assert to ensure size! = 0 to detect bugs. This is the contradiction between Defensive Programming and hiding bugs. Refer to the processing (assert) of null pointers in ffreemory ).
5.5.write functions that, given valid inputs, cannot fail.
Write a function that does not fail as long as the input is valid.
[Note] like the tolower function, many people prefer to design it 1 Char To1ower ( Char Ch)
2 {
3 If (CH > = ' A ' && Ch <= ' Z ' )
4 Return (CH + ' A ' - ' A ' );
5 Else
6 Return ( - 1 );
7 }
This is also an example where the returned value contains too much information. For more information about its disadvantages, see the previous section. Of course you can improve it as before. However, you always need to perform the runtime check. If the improvements are as follows: 1 Char Tolower ( Char Ch)
2 {
3 Assert (CH > = ' A ' && Ch <= ' Z ' );
4 Return (CH + ' A ' - ' A ' );
5 }
In this way, the user never needs to perform the runtime error check, which reduces the caller's code volume and the possibility of errors (the debug version has been assert). This is actually the role of the debug version.
5.6.make the code intelligible at the point of call. Avoid Boolean arguments.
This makes the code (called function) easy to understand. Avoid Boolean parameters.
[Note] Boolean parameters are not easily extended.
5.7.write comments that emphasize potential hazards.
Write comments to emphasize potential risks.